libhashkit: fix UB on unaligned access
authorMichael Wallner <mike@php.net>
Tue, 14 Jan 2020 12:10:48 +0000 (13:10 +0100)
committerMichael Wallner <mike@php.net>
Tue, 14 Jan 2020 12:10:48 +0000 (13:10 +0100)
optimizations will produce similar instructions anyway

libhashkit/murmur.cc
libhashkit/murmur3.cc

index 3bdacf0e4e8a2e3371af9af3f28fd4ff1ca72b4b..f3e8fe6ac7eebcca2d92d72e69d19e249aed2934 100644 (file)
@@ -56,6 +56,8 @@
 
 #ifdef HAVE_MURMUR_HASH
 
+#include <cstring>
+
 uint32_t hashkit_murmur(const char *key, size_t length, void *context)
 {
   /*
@@ -79,7 +81,8 @@ uint32_t hashkit_murmur(const char *key, size_t length, void *context)
 
   while(length >= 4)
   {
-    unsigned int k = *(unsigned int *)data;
+    unsigned int k;
+    memcpy(&k, data, sizeof(unsigned int));
 
     k *= m;
     k ^= k >> r;
index 6e2f8ed8db6c773d95d0cd17f2a5fb86a923530c..8d86cfd859cca7e11d6afa72055572d75d6965e5 100644 (file)
@@ -39,7 +39,13 @@ static FORCE_INLINE uint64_t rotl64 ( uint64_t x, int8_t r )
 // Block read - if your platform needs to do endian-swapping or can only
 // handle aligned reads, do the conversion here
 
-#define getblock(p, i) (p[i])
+#include <cstring>
+template <typename T>
+static inline T getblock(const T *blocks, int i) {
+  T b;
+  memcpy(&b, ((const uint8_t *) blocks) + i * sizeof(T), sizeof(T));
+  return b;
+}
 
 //-----------------------------------------------------------------------------
 // Finalization mix - force all bits of a hash block to avalanche