summaryrefslogtreecommitdiffstats
path: root/document
diff options
context:
space:
mode:
authorTor Brede Vekterli <vekterli@yahooinc.com>2022-03-28 11:38:41 +0000
committerTor Brede Vekterli <vekterli@yahooinc.com>2022-03-28 12:35:52 +0000
commitf0f199001503b8f649a0cbb44261657f1bfd0cb3 (patch)
treef203b56320597797607d42276500246ed97dd9d7 /document
parentf586464b27375f090d85b030bd8294fd2db51de2 (diff)
Handle unaligned IdString reads in a well-defined manner
Should compile down to effectively the same instructions on x86-64, and might save us some headaches on architectures that are less lenient with data alignment for reads.
Diffstat (limited to 'document')
-rw-r--r--document/src/vespa/document/base/idstring.cpp18
1 files changed, 16 insertions, 2 deletions
diff --git a/document/src/vespa/document/base/idstring.cpp b/document/src/vespa/document/base/idstring.cpp
index a364ffd90ce..f3e41981c8e 100644
--- a/document/src/vespa/document/base/idstring.cpp
+++ b/document/src/vespa/document/base/idstring.cpp
@@ -110,13 +110,27 @@ fmemchr(const char * s, const char * e)
#endif
}
+namespace {
+
+// Avoid issues with primitive alignment when reading from buffer.
+// Requires caller to ensure buffer is big enough to read from.
+template <typename T>
+inline T read_unaligned(const char* buf) noexcept
+{
+ T tmp;
+ memcpy(&tmp, buf, sizeof(T));
+ return tmp;
+}
+
+}
+
void
verifyIdString(const char * id, size_t sz_)
{
if (sz_ > 4) {
- if (_G_id.as16 == *reinterpret_cast<const uint16_t *>(id) && id[2] == ':') {
+ if ((_G_id.as16 == read_unaligned<uint16_t>(id)) && (id[2] == ':')) {
return;
- } else if ((sz_ == 6) && (_G_null.as32 == *reinterpret_cast<const uint32_t *>(id)) && (id[4] == ':') && (id[5] == ':')) {
+ } else if ((sz_ == 6) && (_G_null.as32 == read_unaligned<uint32_t>(id)) && (id[4] == ':') && (id[5] == ':')) {
reportNoId(id);
} else if (sz_ > 8) {
reportNoSchemeSeparator(id);