Merge pull request #726 from grynca/master

fix unaligned access in murmur hash
This commit is contained in:
Micha Mettke 2018-10-21 00:20:34 +02:00 committed by GitHub
commit 19c14bb777
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 38 additions and 26 deletions

View File

@ -7164,23 +7164,29 @@ nk_murmur_hash(const void * key, int len, nk_hash seed)
{ {
/* 32-Bit MurmurHash3: https://code.google.com/p/smhasher/wiki/MurmurHash3*/ /* 32-Bit MurmurHash3: https://code.google.com/p/smhasher/wiki/MurmurHash3*/
#define NK_ROTL(x,r) ((x) << (r) | ((x) >> (32 - r))) #define NK_ROTL(x,r) ((x) << (r) | ((x) >> (32 - r)))
union {const nk_uint *i; const nk_byte *b;} conv = {0};
const nk_byte *data = (const nk_byte*)key;
const int nblocks = len/4;
nk_uint h1 = seed; nk_uint h1 = seed;
nk_uint k1;
const nk_byte *data = (const nk_byte*)key;
const nk_byte *keyptr = data;
nk_byte *k1ptr;
const int bsize = sizeof(k1);
const int nblocks = len/4;
const nk_uint c1 = 0xcc9e2d51; const nk_uint c1 = 0xcc9e2d51;
const nk_uint c2 = 0x1b873593; const nk_uint c2 = 0x1b873593;
const nk_byte *tail; const nk_byte *tail;
const nk_uint *blocks;
nk_uint k1;
int i; int i;
/* body */ /* body */
if (!key) return 0; if (!key) return 0;
conv.b = (data + nblocks*4); for (i = 0; i < nblocks; ++i, keyptr += bsize) {
blocks = (const nk_uint*)conv.i; k1ptr = (nk_byte*)&k1;
for (i = -nblocks; i; ++i) { k1ptr[0] = keyptr[0];
k1 = blocks[i]; k1ptr[1] = keyptr[1];
k1ptr[2] = keyptr[2];
k1ptr[3] = keyptr[3];
k1 *= c1; k1 *= c1;
k1 = NK_ROTL(k1,15); k1 = NK_ROTL(k1,15);
k1 *= c2; k1 *= c2;
@ -7194,15 +7200,15 @@ nk_murmur_hash(const void * key, int len, nk_hash seed)
tail = (const nk_byte*)(data + nblocks*4); tail = (const nk_byte*)(data + nblocks*4);
k1 = 0; k1 = 0;
switch (len & 3) { switch (len & 3) {
case 3: k1 ^= (nk_uint)(tail[2] << 16); /* fallthrough */ case 3: k1 ^= (nk_uint)(tail[2] << 16); /* fallthrough */
case 2: k1 ^= (nk_uint)(tail[1] << 8u); /* fallthrough */ case 2: k1 ^= (nk_uint)(tail[1] << 8u); /* fallthrough */
case 1: k1 ^= tail[0]; case 1: k1 ^= tail[0];
k1 *= c1; k1 *= c1;
k1 = NK_ROTL(k1,15); k1 = NK_ROTL(k1,15);
k1 *= c2; k1 *= c2;
h1 ^= k1; h1 ^= k1;
break; break;
default: break; default: break;
} }
/* finalization */ /* finalization */

View File

@ -914,23 +914,29 @@ nk_murmur_hash(const void * key, int len, nk_hash seed)
{ {
/* 32-Bit MurmurHash3: https://code.google.com/p/smhasher/wiki/MurmurHash3*/ /* 32-Bit MurmurHash3: https://code.google.com/p/smhasher/wiki/MurmurHash3*/
#define NK_ROTL(x,r) ((x) << (r) | ((x) >> (32 - r))) #define NK_ROTL(x,r) ((x) << (r) | ((x) >> (32 - r)))
union {const nk_uint *i; const nk_byte *b;} conv = {0};
const nk_byte *data = (const nk_byte*)key;
const int nblocks = len/4;
nk_uint h1 = seed; nk_uint h1 = seed;
nk_uint k1;
const nk_byte *data = (const nk_byte*)key;
const nk_byte *keyptr = data;
nk_byte *k1ptr;
const int bsize = sizeof(k1);
const int nblocks = len/4;
const nk_uint c1 = 0xcc9e2d51; const nk_uint c1 = 0xcc9e2d51;
const nk_uint c2 = 0x1b873593; const nk_uint c2 = 0x1b873593;
const nk_byte *tail; const nk_byte *tail;
const nk_uint *blocks;
nk_uint k1;
int i; int i;
/* body */ /* body */
if (!key) return 0; if (!key) return 0;
conv.b = (data + nblocks*4); for (i = 0; i < nblocks; ++i, keyptr += bsize) {
blocks = (const nk_uint*)conv.i; k1ptr = (nk_byte*)&k1;
for (i = -nblocks; i; ++i) { k1ptr[0] = keyptr[0];
k1 = blocks[i]; k1ptr[1] = keyptr[1];
k1ptr[2] = keyptr[2];
k1ptr[3] = keyptr[3];
k1 *= c1; k1 *= c1;
k1 = NK_ROTL(k1,15); k1 = NK_ROTL(k1,15);
k1 *= c2; k1 *= c2;
@ -944,15 +950,15 @@ nk_murmur_hash(const void * key, int len, nk_hash seed)
tail = (const nk_byte*)(data + nblocks*4); tail = (const nk_byte*)(data + nblocks*4);
k1 = 0; k1 = 0;
switch (len & 3) { switch (len & 3) {
case 3: k1 ^= (nk_uint)(tail[2] << 16); /* fallthrough */ case 3: k1 ^= (nk_uint)(tail[2] << 16); /* fallthrough */
case 2: k1 ^= (nk_uint)(tail[1] << 8u); /* fallthrough */ case 2: k1 ^= (nk_uint)(tail[1] << 8u); /* fallthrough */
case 1: k1 ^= tail[0]; case 1: k1 ^= tail[0];
k1 *= c1; k1 *= c1;
k1 = NK_ROTL(k1,15); k1 = NK_ROTL(k1,15);
k1 *= c2; k1 *= c2;
h1 ^= k1; h1 ^= k1;
break; break;
default: break; default: break;
} }
/* finalization */ /* finalization */