You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by ju...@apache.org on 2011/01/21 20:19:51 UTC
svn commit: r1061974 - in /commons/proper/codec/trunk/src:
java/org/apache/commons/codec/binary/Base64InputStream.java
test/org/apache/commons/codec/binary/Base64InputStreamTest.java
test/org/apache/commons/codec/binary/Base64TestData.java
Author: julius
Date: Fri Jan 21 19:19:51 2011
New Revision: 1061974
URL: http://svn.apache.org/viewvc?rev=1061974&view=rev
Log:
Fix for CODEC-101: java.io.InputStreamReader hates it when InputStream.read(byte[]) returns a zero.
Modified:
commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/Base64InputStream.java
commons/proper/codec/trunk/src/test/org/apache/commons/codec/binary/Base64InputStreamTest.java
commons/proper/codec/trunk/src/test/org/apache/commons/codec/binary/Base64TestData.java
Modified: commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/Base64InputStream.java
URL: http://svn.apache.org/viewvc/commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/Base64InputStream.java?rev=1061974&r1=1061973&r2=1061974&view=diff
==============================================================================
--- commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/Base64InputStream.java (original)
+++ commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/Base64InputStream.java Fri Jan 21 19:19:51 2011
@@ -145,21 +145,41 @@ public class Base64InputStream extends F
} else if (len == 0) {
return 0;
} else {
- if (!base64.hasData()) {
- byte[] buf = new byte[doEncode ? 4096 : 8192];
- int c = in.read(buf);
- // A little optimization to avoid System.arraycopy()
- // when possible.
- if (c > 0 && b.length == len) {
- base64.setInitialBuffer(b, offset, len);
- }
- if (doEncode) {
- base64.encode(buf, 0, c);
- } else {
- base64.decode(buf, 0, c);
+ int readLen = 0;
+ /*
+ Rationale for while-loop on (readLen == 0):
+ -----
+ Base64.readResults() usually returns > 0 or EOF (-1). In the
+ rare case where it returns 0, we just keep trying.
+
+ This is essentially an undocumented contract for InputStream
+ implementors that want their code to work properly with
+ java.io.InputStreamReader, since the latter hates it when
+ InputStream.read(byte[]) returns a zero. Unfortunately our
+ readResults() call must return 0 if a large amount of the data
+ being decoded was non-base64, so this while-loop enables proper
+ interop with InputStreamReader for that scenario.
+ -----
+ This is a fix for CODEC-101
+ */
+ while (readLen == 0) {
+ if (!base64.hasData()) {
+ byte[] buf = new byte[doEncode ? 4096 : 8192];
+ int c = in.read(buf);
+ // A little optimization to avoid System.arraycopy()
+ // when possible.
+ if (c > 0 && b.length == len) {
+ base64.setInitialBuffer(b, offset, len);
+ }
+ if (doEncode) {
+ base64.encode(buf, 0, c);
+ } else {
+ base64.decode(buf, 0, c);
+ }
}
+ readLen = base64.readResults(b, offset, len);
}
- return base64.readResults(b, offset, len);
+ return readLen;
}
}
Modified: commons/proper/codec/trunk/src/test/org/apache/commons/codec/binary/Base64InputStreamTest.java
URL: http://svn.apache.org/viewvc/commons/proper/codec/trunk/src/test/org/apache/commons/codec/binary/Base64InputStreamTest.java?rev=1061974&r1=1061973&r2=1061974&view=diff
==============================================================================
--- commons/proper/codec/trunk/src/test/org/apache/commons/codec/binary/Base64InputStreamTest.java (original)
+++ commons/proper/codec/trunk/src/test/org/apache/commons/codec/binary/Base64InputStreamTest.java Fri Jan 21 19:19:51 2011
@@ -47,6 +47,24 @@ public class Base64InputStreamTest exten
}
/**
+ * Test for the CODEC-101 bug: InputStream.read(byte[]) should never return 0
+ * because Java's builtin InputStreamReader hates that.
+ *
+ * @throws Exception for some failure scenarios.
+ */
+ public void testCodec101() throws Exception {
+ byte[] codec101 = StringUtils.getBytesUtf8(Base64TestData.CODEC_101_MULTIPLE_OF_3);
+ ByteArrayInputStream bais = new ByteArrayInputStream(codec101);
+ Base64InputStream in = new Base64InputStream(bais);
+ byte[] result = new byte[8192];
+ int c = in.read(result);
+ assertTrue("Codec101: First read successful [c=" + c + "]", c > 0);
+
+ c = in.read(result);
+ assertTrue("Codec101: Second read should report end-of-stream [c=" + c + "]", c < 0);
+ }
+
+ /**
* Test the Base64InputStream implementation against the special NPE inducing input
* identified in the CODEC-98 bug.
*
Modified: commons/proper/codec/trunk/src/test/org/apache/commons/codec/binary/Base64TestData.java
URL: http://svn.apache.org/viewvc/commons/proper/codec/trunk/src/test/org/apache/commons/codec/binary/Base64TestData.java?rev=1061974&r1=1061973&r2=1061974&view=diff
==============================================================================
--- commons/proper/codec/trunk/src/test/org/apache/commons/codec/binary/Base64TestData.java (original)
+++ commons/proper/codec/trunk/src/test/org/apache/commons/codec/binary/Base64TestData.java Fri Jan 21 19:19:51 2011
@@ -32,6 +32,8 @@ import java.util.Random;
*/
public class Base64TestData {
+ public static final String CODEC_101_MULTIPLE_OF_3 = "123";
+
public static final String CODEC_98_NPE
= "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWjAxMjM";