luci-base: further hash calculation signedness bugfixes
- cbi.js: make sure to treat single bytes as signed char when handling end cases - template_lmo.c: make sure to treat single bytes as signed char when handling end cases, avoids hash miscalculations on ARM Signed-off-by: Jo-Philipp Wich <jo@mein.io>
This commit is contained in:
parent
c55436e36f
commit
51de74d520
2 changed files with 17 additions and 8 deletions
|
@ -15,6 +15,15 @@ var cbi_d = [];
|
||||||
var cbi_t = [];
|
var cbi_t = [];
|
||||||
var cbi_strings = { path: {}, label: {} };
|
var cbi_strings = { path: {}, label: {} };
|
||||||
|
|
||||||
|
function s8(bytes, off) {
|
||||||
|
var n = bytes[off];
|
||||||
|
return (n > 0x7F) ? (n - 256) >>> 0 : n;
|
||||||
|
}
|
||||||
|
|
||||||
|
function u16(bytes, off) {
|
||||||
|
return ((bytes[off + 1] << 8) + bytes[off]) >>> 0;
|
||||||
|
}
|
||||||
|
|
||||||
function sfh(s) {
|
function sfh(s) {
|
||||||
if (s === null || s.length === 0)
|
if (s === null || s.length === 0)
|
||||||
return null;
|
return null;
|
||||||
|
@ -48,8 +57,8 @@ function sfh(s) {
|
||||||
off = 0, tmp;
|
off = 0, tmp;
|
||||||
|
|
||||||
while (len--) {
|
while (len--) {
|
||||||
hash += ((bytes[off + 1] << 8) + bytes[off]) >>> 0;
|
hash += u16(bytes, off);
|
||||||
tmp = ((((bytes[off + 3] << 8) + bytes[off + 2]) << 11) ^ hash) >>> 0;
|
tmp = ((u16(bytes, off + 2) << 11) ^ hash) >>> 0;
|
||||||
hash = ((hash << 16) ^ tmp) >>> 0;
|
hash = ((hash << 16) ^ tmp) >>> 0;
|
||||||
hash += hash >>> 11;
|
hash += hash >>> 11;
|
||||||
off += 4;
|
off += 4;
|
||||||
|
@ -57,20 +66,20 @@ function sfh(s) {
|
||||||
|
|
||||||
switch ((bytes.length & 3) >>> 0) {
|
switch ((bytes.length & 3) >>> 0) {
|
||||||
case 3:
|
case 3:
|
||||||
hash += ((bytes[off + 1] << 8) + bytes[off]) >>> 0;
|
hash += u16(bytes, off);
|
||||||
hash = (hash ^ (hash << 16)) >>> 0;
|
hash = (hash ^ (hash << 16)) >>> 0;
|
||||||
hash = (hash ^ (bytes[off + 2] << 18)) >>> 0;
|
hash = (hash ^ (s8(bytes, off + 2) << 18)) >>> 0;
|
||||||
hash += hash >>> 11;
|
hash += hash >>> 11;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
hash += ((bytes[off + 1] << 8) + bytes[off]) >>> 0;
|
hash += u16(bytes, off);
|
||||||
hash = (hash ^ (hash << 11)) >>> 0;
|
hash = (hash ^ (hash << 11)) >>> 0;
|
||||||
hash += hash >>> 17;
|
hash += hash >>> 17;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
hash += bytes[off];
|
hash += s8(bytes, off);
|
||||||
hash = (hash ^ (hash << 10)) >>> 0;
|
hash = (hash ^ (hash << 10)) >>> 0;
|
||||||
hash += hash >>> 1;
|
hash += hash >>> 1;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -46,14 +46,14 @@ uint32_t sfh_hash(const char *data, int len)
|
||||||
switch (rem) {
|
switch (rem) {
|
||||||
case 3: hash += sfh_get16(data);
|
case 3: hash += sfh_get16(data);
|
||||||
hash ^= hash << 16;
|
hash ^= hash << 16;
|
||||||
hash ^= data[sizeof(uint16_t)] << 18;
|
hash ^= (signed char)data[sizeof(uint16_t)] << 18;
|
||||||
hash += hash >> 11;
|
hash += hash >> 11;
|
||||||
break;
|
break;
|
||||||
case 2: hash += sfh_get16(data);
|
case 2: hash += sfh_get16(data);
|
||||||
hash ^= hash << 11;
|
hash ^= hash << 11;
|
||||||
hash += hash >> 17;
|
hash += hash >> 17;
|
||||||
break;
|
break;
|
||||||
case 1: hash += *data;
|
case 1: hash += (signed char)*data;
|
||||||
hash ^= hash << 10;
|
hash ^= hash << 10;
|
||||||
hash += hash >> 1;
|
hash += hash >> 1;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue