]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
rec: fix unaligned access is murmur hash code used by NOD
authorOtto Moerbeek <otto.moerbeek@open-xchange.com>
Tue, 22 Feb 2022 13:26:26 +0000 (14:26 +0100)
committerOtto Moerbeek <otto.moerbeek@open-xchange.com>
Tue, 22 Feb 2022 15:21:25 +0000 (16:21 +0100)
pdns/recursordist/stable-bloom.hh

index 3fc14cce8986effc9eda984bcf9bf0877cae6a4d..877ed19f369629eb0e60b646a156980de4a392a9 100644 (file)
@@ -28,6 +28,7 @@
 #include <arpa/inet.h>
 #include <boost/dynamic_bitset.hpp>
 #include "misc.hh"
+#include "noinitvector.hh"
 #include "ext/probds/murmur3.h"
 
 namespace bf
@@ -164,8 +165,18 @@ private:
   std::vector<uint32_t> hash(const std::string& data) const
   {
     uint32_t h1, h2;
-    MurmurHash3_x86_32(data.c_str(), data.length(), 1, (void*)&h1);
-    MurmurHash3_x86_32(data.c_str(), data.length(), 2, (void*)&h2);
+    // MurmurHash3 assumes the data is uint32_t aligned, so fixup if needed
+    // It does handle string lengths that are not a multiple of sizeof(uint32_t) correctly
+    if (reinterpret_cast<uintptr_t>(data.data()) % sizeof(uint32_t) != 0) {
+      NoInitVector<uint32_t> x((data.length() / sizeof(int32_t)) + 1);
+      memcpy(x.data(), data.data(), data.length());
+      MurmurHash3_x86_32(x.data(), data.length(), 1, &h1);
+      MurmurHash3_x86_32(x.data(), data.length(), 2, &h2);
+    }
+    else {
+      MurmurHash3_x86_32(data.data(), data.length(), 1, &h1);
+      MurmurHash3_x86_32(data.data(), data.length(), 2, &h2);
+    }
     std::vector<uint32_t> ret_hashes(d_k);
     for (size_t i = 0; i < d_k; ++i) {
       ret_hashes[i] = h1 + i * h2;