Skip to content

Commit

Permalink
PlatformDependent ASCII hash code broken on big endian machines
Browse files Browse the repository at this point in the history
Motivation:
PlatformDependent has a hash code algorithm which utilizes UNSAFE for performance reasons. This hash code algorithm must also be consistent with CharSequence objects that represent a collection of ASCII characters. In order to make the UNSAFE versions and CharSequence versions the endianness should be taken into account. However the big endian code was not correct in a few places.

Modifications:
- Correct bugs in PlatformDependent class related to big endian ASCII hash code computation

Result:
Fixes netty#5925
  • Loading branch information
Scottmitch committed Oct 24, 2016
1 parent cfa5b85 commit 9cfa467
Showing 1 changed file with 9 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -439,7 +439,7 @@ private static long getLongSafe(byte[] bytes, int offset) {
((long) bytes[offset + 4] & 0xff) << 32 |
((long) bytes[offset + 5] & 0xff) << 40 |
((long) bytes[offset + 6] & 0xff) << 48 |
((long) bytes[offset + 7] & 0xff) << 56;
(long) bytes[offset + 7] << 56;
}

private static int getIntSafe(byte[] bytes, int offset) {
Expand All @@ -466,8 +466,13 @@ private static short getShortSafe(byte[] bytes, int offset) {
* Identical to {@link PlatformDependent0#hashCodeAsciiCompute(long, int)} but for {@link CharSequence}.
*/
private static int hashCodeAsciiCompute(CharSequence value, int offset, int hash) {
// masking with 0x1f reduces the number of overall bits that impact the hash code but makes the hash
// code the same regardless of character case (upper case or lower case hash is the same).
if (BIG_ENDIAN_NATIVE_ORDER) {
return hash * HASH_CODE_C1 +
// Low order int
hashCodeAsciiSanitizeInt(value, offset + 4) * HASH_CODE_C2 +
// High order int
hashCodeAsciiSanitizeInt(value, offset);
}
return hash * HASH_CODE_C1 +
// Low order int
hashCodeAsciiSanitizeInt(value, offset) * HASH_CODE_C2 +
Expand All @@ -481,7 +486,7 @@ private static int hashCodeAsciiCompute(CharSequence value, int offset, int hash
private static int hashCodeAsciiSanitizeInt(CharSequence value, int offset) {
if (BIG_ENDIAN_NATIVE_ORDER) {
// mimic a unsafe.getInt call on a big endian machine
return (value.charAt(offset) & 0x1f) |
return (value.charAt(offset + 3) & 0x1f) |
(value.charAt(offset + 2) & 0x1f) << 8 |
(value.charAt(offset + 1) & 0x1f) << 16 |
(value.charAt(offset) & 0x1f) << 24;
Expand Down

0 comments on commit 9cfa467

Please sign in to comment.