Skip to content

Commit 33491ff

Browse files
committed
Overflow safe position counter in XXHash32.
1 parent a387ac8 commit 33491ff

1 file changed

Lines changed: 15 additions & 3 deletions

File tree

src/main/java/org/apache/commons/codec/digest/XXHash32.java

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ public class XXHash32 implements Checksum {
5555

5656
private int totalLen;
5757
private int pos;
58+
/** Set to true when the state array has been updated since the last reset. */
59+
private boolean stateUpdated;
5860

5961
/**
6062
* Creates an XXHash32 instance with a seed of 0.
@@ -77,6 +79,7 @@ public void reset() {
7779
initializeState();
7880
totalLen = 0;
7981
pos = 0;
82+
stateUpdated = false;
8083
}
8184

8285
@Override
@@ -94,12 +97,16 @@ public void update(final byte[] b, int off, final int len) {
9497

9598
final int end = off + len;
9699

97-
if (pos + len < BUF_SIZE) {
100+
// Check if the unprocessed bytes and new bytes can fill a block of 16.
101+
// Make this overflow safe in the event that len is Integer.MAX_VALUE.
102+
// Equivalent to: (pos + len < BUF_SIZE)
103+
if (pos + len - BUF_SIZE < 0) {
98104
System.arraycopy(b, off, buffer, pos, len);
99105
pos += len;
100106
return;
101107
}
102108

109+
// Process left-over bytes with new bytes
103110
if (pos > 0) {
104111
final int size = BUF_SIZE - pos;
105112
System.arraycopy(b, off, buffer, pos, size);
@@ -113,22 +120,27 @@ public void update(final byte[] b, int off, final int len) {
113120
off += BUF_SIZE;
114121
}
115122

123+
// Handle left-over bytes
116124
if (off < end) {
117125
pos = end - off;
118126
System.arraycopy(b, off, buffer, 0, pos);
127+
} else {
128+
pos = 0;
119129
}
120130
}
121131

122132
@Override
123133
public long getValue() {
124134
int hash;
125-
if (totalLen > BUF_SIZE) {
135+
if (stateUpdated) {
136+
// Hash with the state
126137
hash =
127138
rotateLeft(state[0], 1) +
128139
rotateLeft(state[1], 7) +
129140
rotateLeft(state[2], 12) +
130141
rotateLeft(state[3], 18);
131142
} else {
143+
// Hash using the original seed from position 2
132144
hash = state[2] + PRIME5;
133145
}
134146
hash += totalLen;
@@ -178,7 +190,7 @@ private void process(final byte[] b, final int offset) {
178190
state[2] = s2;
179191
state[3] = s3;
180192

181-
pos = 0;
193+
stateUpdated = true;
182194
}
183195

184196
/**

0 commit comments

Comments
 (0)