Handle unaligned keys in hash().
Reported by Christopher Ferris <cferris@google.com>.
This commit is contained in:
parent
9f24c94474
commit
a0aaad1afa
@ -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]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user