This is an automated email from the ASF dual-hosted git repository. aherbert pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/commons-codec.git
commit 33491ff84299cc1a48031fba066e6e69f21e1861 Author: Alex Herbert <aherb...@apache.org> AuthorDate: Mon Dec 30 21:40:17 2019 +0000 Overflow safe position counter in XXHash32. --- .../java/org/apache/commons/codec/digest/XXHash32.java | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/apache/commons/codec/digest/XXHash32.java b/src/main/java/org/apache/commons/codec/digest/XXHash32.java index 0d81e0a..0fce378 100644 --- a/src/main/java/org/apache/commons/codec/digest/XXHash32.java +++ b/src/main/java/org/apache/commons/codec/digest/XXHash32.java @@ -55,6 +55,8 @@ public class XXHash32 implements Checksum { private int totalLen; private int pos; + /** Set to true when the state array has been updated since the last reset. */ + private boolean stateUpdated; /** * Creates an XXHash32 instance with a seed of 0. @@ -77,6 +79,7 @@ public class XXHash32 implements Checksum { initializeState(); totalLen = 0; pos = 0; + stateUpdated = false; } @Override @@ -94,12 +97,16 @@ public class XXHash32 implements Checksum { final int end = off + len; - if (pos + len < BUF_SIZE) { + // Check if the unprocessed bytes and new bytes can fill a block of 16. + // Make this overflow safe in the event that len is Integer.MAX_VALUE. + // Equivalent to: (pos + len < BUF_SIZE) + if (pos + len - BUF_SIZE < 0) { System.arraycopy(b, off, buffer, pos, len); pos += len; return; } + // Process left-over bytes with new bytes if (pos > 0) { final int size = BUF_SIZE - pos; System.arraycopy(b, off, buffer, pos, size); @@ -113,22 +120,27 @@ public class XXHash32 implements Checksum { off += BUF_SIZE; } + // Handle left-over bytes if (off < end) { pos = end - off; System.arraycopy(b, off, buffer, 0, pos); + } else { + pos = 0; } } @Override public long getValue() { int hash; - if (totalLen > BUF_SIZE) { + if (stateUpdated) { + // Hash with the state hash = rotateLeft(state[0], 1) + rotateLeft(state[1], 7) + rotateLeft(state[2], 12) + rotateLeft(state[3], 18); } else { + // Hash using the original seed from position 2 hash = state[2] + PRIME5; } hash += totalLen; @@ -178,7 +190,7 @@ public class XXHash32 implements Checksum { state[2] = s2; state[3] = s3; - pos = 0; + stateUpdated = true; } /**