Skip to content

Commit 7ccbc3d

Browse files
abFlorian Lechner
authored andcommitted
CODEC-305: Fix byte-skipping in Base16 decoding
1 parent b22276d commit 7ccbc3d

2 files changed

Lines changed: 26 additions & 6 deletions

File tree

src/main/java/org/apache/commons/codec/binary/Base16.java

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -169,34 +169,33 @@ void decode(final byte[] data, int offset, final int length, final Context conte
169169

170170
// we must have an even number of chars to decode
171171
final int charsToProcess = availableChars % BYTES_PER_ENCODED_BLOCK == 0 ? availableChars : availableChars - 1;
172+
final int end = offset + dataLen;
172173

173174
final byte[] buffer = ensureBufferSize(charsToProcess / BYTES_PER_ENCODED_BLOCK, context);
174175

175176
int result;
176-
int i = 0;
177177
if (dataLen < availableChars) {
178178
// we have 1/2 byte from previous invocation to decode
179179
result = (context.ibitWorkArea - 1) << BITS_PER_ENCODED_BYTE;
180180
result |= decodeOctet(data[offset++]);
181-
i = 2;
182181

183182
buffer[context.pos++] = (byte)result;
184183

185184
// reset to empty-value for next invocation!
186185
context.ibitWorkArea = 0;
187186
}
188187

189-
while (i < charsToProcess) {
188+
final int loopEnd = end - 1;
189+
while (offset < loopEnd) {
190190
result = decodeOctet(data[offset++]) << BITS_PER_ENCODED_BYTE;
191191
result |= decodeOctet(data[offset++]);
192-
i += 2;
193192
buffer[context.pos++] = (byte)result;
194193
}
195194

196195
// we have one char of a hex-pair left over
197-
if (i < dataLen) {
196+
if (offset < end) {
198197
// store 1/2 byte for next invocation of decode, we offset by +1 as empty-value is 0
199-
context.ibitWorkArea = decodeOctet(data[i]) + 1;
198+
context.ibitWorkArea = decodeOctet(data[offset]) + 1;
200199
}
201200
}
202201

src/test/java/org/apache/commons/codec/binary/Base16Test.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -577,4 +577,25 @@ public void testLenientDecoding() {
577577
final byte[] decoded = b16.decode(StringUtils.getBytesUtf8(encoded));
578578
assertArrayEquals(new byte[] {(byte)0xaa, (byte)0xbb, (byte)0xcc, (byte)0xdd}, decoded);
579579
}
580+
581+
@Test
582+
public void testOddEvenDecoding() {
583+
final String encoded = "4142434445";
584+
585+
final BaseNCodec.Context context = new BaseNCodec.Context();
586+
final Base16 base16 = new Base16();
587+
588+
final byte[] encodedBytes = StringUtils.getBytesUtf8(encoded);
589+
590+
// pass odd, then even, then odd amount of data
591+
base16.decode(encodedBytes, 0, 3, context);
592+
base16.decode(encodedBytes, 3, 4, context);
593+
base16.decode(encodedBytes, 7, 3, context);
594+
595+
final byte[] decodedBytes = new byte[context.pos];
596+
System.arraycopy(context.buffer, context.readPos, decodedBytes, 0, decodedBytes.length);
597+
final String decoded = StringUtils.newStringUtf8(decodedBytes);
598+
599+
assertEquals("ABCDE", decoded);
600+
}
580601
}

0 commit comments

Comments
 (0)