Skip to content

Commit 800f053

Browse files
author
Julius Davies
committed
CODEC-98 - Base64InputStream causes NullPointerException on some input - https://issues.apache.org/jira/browse/CODEC-98
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/codec/trunk@950267 13f79535-47bb-0310-9956-ffa450edef68
1 parent 4c6eea4 commit 800f053

4 files changed

Lines changed: 58 additions & 1 deletion

File tree

src/java/org/apache/commons/codec/binary/Base64.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -583,6 +583,10 @@ void decode(byte[] in, int inPos, int inAvail) {
583583
// EOF (-1) and first time '=' character is encountered in stream.
584584
// This approach makes the '=' padding characters completely optional.
585585
if (eof && modulus != 0) {
586+
if (buffer == null || buffer.length - pos < decodeSize) {
587+
resizeBuffer();
588+
}
589+
586590
x = x << 6;
587591
switch (modulus) {
588592
case 2 :

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

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,26 @@ public Base64InputStreamTest(String name) {
4646
super(name);
4747
}
4848

49+
/**
50+
* Test the Base64InputStream implementation against the special NPE inducing input
51+
* identified in the CODEC-98 bug.
52+
*
53+
* @throws Exception for some failure scenarios.
54+
*/
55+
public void testCodec98NPE() throws Exception {
56+
byte[] codec98 = StringUtils.getBytesUtf8(Base64TestData.CODEC_98_NPE);
57+
ByteArrayInputStream data = new ByteArrayInputStream(codec98);
58+
Base64InputStream stream = new Base64InputStream(data);
59+
60+
// This line causes an NPE in commons-codec-1.4.jar:
61+
byte[] decodedBytes = Base64TestData.streamToBytes(stream, new byte[1024]);
62+
63+
String decoded = StringUtils.newStringUtf8(decodedBytes);
64+
assertEquals(
65+
"codec-98 NPE Base64InputStream", Base64TestData.CODEC_98_NPE_DECODED, decoded
66+
);
67+
}
68+
4969
/**
5070
* Tests the Base64InputStream implementation against empty input.
5171
*

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

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,29 @@ public Base64OutputStreamTest(String name) {
4646
super(name);
4747
}
4848

49+
/**
50+
* Test the Base64OutputStream implementation against the special NPE inducing input
51+
* identified in the CODEC-98 bug.
52+
*
53+
* @throws Exception for some failure scenarios.
54+
*/
55+
public void testCodec98NPE() throws Exception {
56+
byte[] codec98 = StringUtils.getBytesUtf8(Base64TestData.CODEC_98_NPE);
57+
byte[] codec98_1024 = new byte[1024];
58+
System.arraycopy(codec98, 0, codec98_1024, 0, codec98.length);
59+
ByteArrayOutputStream data = new ByteArrayOutputStream(1024);
60+
Base64OutputStream stream = new Base64OutputStream(data, false);
61+
stream.write(codec98_1024, 0, 1024);
62+
stream.close();
63+
64+
byte[] decodedBytes = data.toByteArray();
65+
String decoded = StringUtils.newStringUtf8(decodedBytes);
66+
assertEquals(
67+
"codec-98 NPE Base64OutputStream", Base64TestData.CODEC_98_NPE_DECODED, decoded
68+
);
69+
}
70+
71+
4972
/**
5073
* Test the Base64OutputStream implementation against empty input.
5174
*

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

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,13 @@
3232
*/
3333
public class Base64TestData {
3434

35+
public static final String CODEC_98_NPE
36+
= "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWjAxMjM";
37+
38+
public static final String CODEC_98_NPE_DECODED
39+
= "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123";
40+
41+
3542
// OpenSSL doesn't include the final \n, but it would be annoying beyond belief
3643
// to further parameterize commons-codec to support this pointless variation.
3744
final static String ENCODED_64_CHARS_PER_LINE
@@ -133,7 +140,10 @@ public class Base64TestData {
133140

134141
static byte[] streamToBytes(final InputStream in) throws IOException {
135142
// new byte[7] is obviously quite slow, but helps exercise the code.
136-
byte[] buf = new byte[7];
143+
return streamToBytes(in, new byte[7]);
144+
}
145+
146+
static byte[] streamToBytes(final InputStream in, byte[] buf) throws IOException {
137147
try {
138148
int[] status = fill(buf, 0, in);
139149
int size = status[SIZE_KEY];

0 commit comments

Comments
 (0)