Handle unaligned keys in hash().

Reported by Christopher Ferris <cferris@google.com>.
This commit is contained in:
Jason Evans 2016-02-20 10:23:48 -08:00
parent 9f24c94474
commit a0aaad1afa
2 changed files with 33 additions and 4 deletions

View File

@ -1,6 +1,6 @@
/* /*
* The following hash function is based on MurmurHash3, placed into the public * The following hash function is based on MurmurHash3, placed into the public
* domain by Austin Appleby. See http://code.google.com/p/smhasher/ for * domain by Austin Appleby. See https://github.com/aappleby/smhasher for
* details. * details.
*/ */
/******************************************************************************/ /******************************************************************************/
@ -49,6 +49,14 @@ JEMALLOC_INLINE uint32_t
hash_get_block_32(const uint32_t *p, int i) hash_get_block_32(const uint32_t *p, int i)
{ {
/* Handle unaligned read. */
if (unlikely((uintptr_t)p & (sizeof(uint32_t)-1)) != 0) {
uint32_t ret;
memcpy(&ret, &p[i], sizeof(uint32_t));
return (ret);
}
return (p[i]); return (p[i]);
} }
@ -56,6 +64,14 @@ JEMALLOC_INLINE uint64_t
hash_get_block_64(const uint64_t *p, int i) hash_get_block_64(const uint64_t *p, int i)
{ {
/* Handle unaligned read. */
if (unlikely((uintptr_t)p & (sizeof(uint64_t)-1)) != 0) {
uint64_t ret;
memcpy(&ret, &p[i], sizeof(uint64_t));
return (ret);
}
return (p[i]); return (p[i]);
} }

View File

@ -59,17 +59,17 @@ hash_variant_string(hash_variant_t variant)
} }
} }
#define KEY_SIZE 256
static void static void
hash_variant_verify(hash_variant_t variant) hash_variant_verify_key(hash_variant_t variant, uint8_t *key)
{ {
const size_t hashbytes = hash_variant_bits(variant) / 8; const size_t hashbytes = hash_variant_bits(variant) / 8;
uint8_t key[256];
VARIABLE_ARRAY(uint8_t, hashes, hashbytes * 256); VARIABLE_ARRAY(uint8_t, hashes, hashbytes * 256);
VARIABLE_ARRAY(uint8_t, final, hashbytes); VARIABLE_ARRAY(uint8_t, final, hashbytes);
unsigned i; unsigned i;
uint32_t computed, expected; uint32_t computed, expected;
memset(key, 0, sizeof(key)); memset(key, 0, KEY_SIZE);
memset(hashes, 0, sizeof(hashes)); memset(hashes, 0, sizeof(hashes));
memset(final, 0, sizeof(final)); memset(final, 0, sizeof(final));
@ -139,6 +139,19 @@ hash_variant_verify(hash_variant_t variant)
hash_variant_string(variant), expected, computed); hash_variant_string(variant), expected, computed);
} }
static void
hash_variant_verify(hash_variant_t variant)
{
#define MAX_ALIGN 16
uint8_t key[KEY_SIZE + (MAX_ALIGN - 1)];
unsigned i;
for (i = 0; i < MAX_ALIGN; i++)
hash_variant_verify_key(variant, &key[i]);
#undef MAX_ALIGN
}
#undef KEY_SIZE
TEST_BEGIN(test_hash_x86_32) TEST_BEGIN(test_hash_x86_32)
{ {