1717
1818package org .apache .commons .codec .binary ;
1919
20-
2120import java .io .ByteArrayInputStream ;
2221import java .io .InputStream ;
2322import java .util .Arrays ;
2726/**
2827 * @author Apache Software Foundation
2928 * @version $Id $
29+ * @since 1.4
3030 */
3131public class Base64InputStreamTest extends TestCase {
3232
3333 private final static byte [] CRLF = {(byte ) '\r' , (byte ) '\n' };
34+
3435 private final static byte [] LF = {(byte ) '\n' };
3536
37+ private static final String STRING_FIXTURE = "Hello World" ;
38+
39+ private static final String UTF_8_NAME = "UTF-8" ;
40+
3641 /**
3742 * Construct a new instance of this test case.
38- *
39- * @param name Name of the test case
43+ *
44+ * @param name
45+ * Name of the test case
4046 */
4147 public Base64InputStreamTest (String name ) {
4248 super (name );
4349 }
4450
4551 /**
46- * Test the Base64InputStream implementation against empty input.
47- *
48- * @throws Exception for some failure scenarios.
49- */
52+ * Tests the Base64InputStream implementation against empty input.
53+ *
54+ * @throws Exception
55+ * for some failure scenarios.
56+ */
5057 public void testBase64EmptyInputStream () throws Exception {
5158 byte [] emptyEncoded = new byte [0 ];
5259 byte [] emptyDecoded = new byte [0 ];
@@ -55,89 +62,103 @@ public void testBase64EmptyInputStream() throws Exception {
5562 }
5663
5764 /**
58- * Test the Base64InputStream implementation.
59- *
60- * @throws Exception for some failure scenarios.
65+ * Tests the Base64InputStream implementation.
66+ *
67+ * @throws Exception
68+ * for some failure scenarios.
6169 */
62- public void testBase64InputStreamByteByByte () throws Exception {
70+ public void testBase64InputStreamByChunk () throws Exception {
6371 // Hello World test.
64- byte [] encoded = "SGVsbG8gV29ybGQ=\r \n " .getBytes ("UTF-8" );
65- byte [] decoded = "Hello World" .getBytes ("UTF-8" );
66- testByteByByte (encoded , decoded , 76 , CRLF );
72+ byte [] encoded = "SGVsbG8gV29ybGQ=\r \n " .getBytes (UTF_8_NAME );
73+ byte [] decoded = STRING_FIXTURE .getBytes (UTF_8_NAME );
74+ testByChunk (encoded , decoded , 76 , CRLF );
6775
6876 // Single Byte test.
69- encoded = "AA==\r \n " .getBytes ("UTF-8" );
77+ encoded = "AA==\r \n " .getBytes (UTF_8_NAME );
7078 decoded = new byte []{(byte ) 0 };
71- testByteByByte (encoded , decoded , 76 , CRLF );
79+ testByChunk (encoded , decoded , 76 , CRLF );
7280
7381 // OpenSSL interop test.
74- encoded = Base64TestData .ENCODED .getBytes ("UTF-8" );
82+ encoded = Base64TestData .ENCODED .getBytes (UTF_8_NAME );
7583 decoded = Base64TestData .DECODED ;
76- testByteByByte (encoded , decoded , 64 , LF );
84+ testByChunk (encoded , decoded , 64 , LF );
7785
7886 // Single Line test.
7987 String singleLine = Base64TestData .ENCODED .replaceAll ("\n " , "" );
80- encoded = singleLine .getBytes ("UTF-8" );
88+ encoded = singleLine .getBytes (UTF_8_NAME );
8189 decoded = Base64TestData .DECODED ;
82- testByteByByte (encoded , decoded , 0 , LF );
90+ testByChunk (encoded , decoded , 0 , LF );
91+
92+ // test random data of sizes 0 thru 150
93+ for (int i = 0 ; i <= 150 ; i ++) {
94+ byte [][] randomData = Base64TestData .randomData (i , false );
95+ encoded = randomData [1 ];
96+ decoded = randomData [0 ];
97+ testByChunk (encoded , decoded , 0 , LF );
98+ }
8399 }
84100
85101 /**
86- * Test the Base64InputStream implementation.
87- *
88- * @throws Exception for some failure scenarios.
102+ * Tests the Base64InputStream implementation.
103+ *
104+ * @throws Exception
105+ * for some failure scenarios.
89106 */
90- public void testBase64InputStreamByChunk () throws Exception {
107+ public void testBase64InputStreamByteByByte () throws Exception {
91108 // Hello World test.
92- byte [] encoded = "SGVsbG8gV29ybGQ=\r \n " .getBytes ("UTF-8" );
93- byte [] decoded = "Hello World" .getBytes ("UTF-8" );
94- testByChunk (encoded , decoded , 76 , CRLF );
109+ byte [] encoded = "SGVsbG8gV29ybGQ=\r \n " .getBytes (UTF_8_NAME );
110+ byte [] decoded = STRING_FIXTURE .getBytes (UTF_8_NAME );
111+ testByteByByte (encoded , decoded , 76 , CRLF );
95112
96113 // Single Byte test.
97- encoded = "AA==\r \n " .getBytes ("UTF-8" );
114+ encoded = "AA==\r \n " .getBytes (UTF_8_NAME );
98115 decoded = new byte []{(byte ) 0 };
99- testByChunk (encoded , decoded , 76 , CRLF );
116+ testByteByByte (encoded , decoded , 76 , CRLF );
100117
101118 // OpenSSL interop test.
102- encoded = Base64TestData .ENCODED .getBytes ("UTF-8" );
119+ encoded = Base64TestData .ENCODED .getBytes (UTF_8_NAME );
103120 decoded = Base64TestData .DECODED ;
104- testByChunk (encoded , decoded , 64 , LF );
121+ testByteByByte (encoded , decoded , 64 , LF );
105122
106123 // Single Line test.
107124 String singleLine = Base64TestData .ENCODED .replaceAll ("\n " , "" );
108- encoded = singleLine .getBytes ("UTF-8" );
125+ encoded = singleLine .getBytes (UTF_8_NAME );
109126 decoded = Base64TestData .DECODED ;
110- testByChunk (encoded , decoded , 0 , LF );
111- }
127+ testByteByByte (encoded , decoded , 0 , LF );
112128
129+ // test random data of sizes 0 thru 150
130+ for (int i = 0 ; i <= 150 ; i ++) {
131+ byte [][] randomData = Base64TestData .randomData (i , false );
132+ encoded = randomData [1 ];
133+ decoded = randomData [0 ];
134+ testByteByByte (encoded , decoded , 0 , LF );
135+ }
136+ }
113137
114138 /**
115- * Test method does three tests on the supplied data:
116- * 1. encoded ---[DECODE]--> decoded
117- * 2. decoded ---[ENCODE]--> encoded
118- * 3. decoded ---[WRAP-WRAP-WRAP-etc...] --> decoded
139+ * Tests method does three tests on the supplied data: 1. encoded ---[DECODE]--> decoded 2. decoded ---[ENCODE]-->
140+ * encoded 3. decoded ---[WRAP-WRAP-WRAP-etc...] --> decoded
119141 * <p/>
120- * By "[WRAP-WRAP-WRAP-etc...]" we mean situation where the
121- * Base64InputStream wraps itself in encode and decode mode
142+ * By "[WRAP-WRAP-WRAP-etc...]" we mean situation where the Base64InputStream wraps itself in encode and decode mode
122143 * over and over again.
123- *
124- * @param encoded base64 encoded data
125- * @param decoded the data from above, but decoded
126- * @param chunkSize chunk size (line-length) of the base64 encoded data.
127- * @param seperator Line separator in the base64 encoded data.
128- * @throws Exception Usually signifies a bug in the Base64 commons-codec implementation.
144+ *
145+ * @param encoded
146+ * base64 encoded data
147+ * @param decoded
148+ * the data from above, but decoded
149+ * @param chunkSize
150+ * chunk size (line-length) of the base64 encoded data.
151+ * @param seperator
152+ * Line separator in the base64 encoded data.
153+ * @throws Exception
154+ * Usually signifies a bug in the Base64 commons-codec implementation.
129155 */
130- private void testByteByByte (
131- byte [] encoded , byte [] decoded , int chunkSize , byte [] seperator
132- ) throws Exception {
156+ private void testByChunk (byte [] encoded , byte [] decoded , int chunkSize , byte [] seperator ) throws Exception {
133157
134158 // Start with encode.
135159 InputStream in = new ByteArrayInputStream (decoded );
136160 in = new Base64InputStream (in , true , chunkSize , seperator );
137- byte [] output = new byte [encoded .length ];
138- for (int i = 0 ; i < output .length ; i ++) {
139- output [i ] = (byte ) in .read ();
140- }
161+ byte [] output = Base64TestData .streamToBytes (in );
141162
142163 assertEquals ("EOF" , -1 , in .read ());
143164 assertEquals ("Still EOF" , -1 , in .read ());
@@ -146,55 +167,52 @@ private void testByteByByte(
146167 // Now let's try decode.
147168 in = new ByteArrayInputStream (encoded );
148169 in = new Base64InputStream (in );
149- output = new byte [decoded .length ];
150- for (int i = 0 ; i < output .length ; i ++) {
151- output [i ] = (byte ) in .read ();
152- }
170+ output = Base64TestData .streamToBytes (in );
153171
154172 assertEquals ("EOF" , -1 , in .read ());
155173 assertEquals ("Still EOF" , -1 , in .read ());
156174 assertTrue ("Streaming base64 decode" , Arrays .equals (output , decoded ));
157175
158- // I always wanted to do this! (wrap encoder with decoder etc etc).
176+ // I always wanted to do this! (wrap encoder with decoder etc etc).
159177 in = new ByteArrayInputStream (decoded );
160178 for (int i = 0 ; i < 10 ; i ++) {
161179 in = new Base64InputStream (in , true , chunkSize , seperator );
162180 in = new Base64InputStream (in , false );
163181 }
164- output = new byte [decoded .length ];
165- for (int i = 0 ; i < output .length ; i ++) {
166- output [i ] = (byte ) in .read ();
167- }
182+ output = Base64TestData .streamToBytes (in );
168183
169184 assertEquals ("EOF" , -1 , in .read ());
170185 assertEquals ("Still EOF" , -1 , in .read ());
171186 assertTrue ("Streaming base64 wrap-wrap-wrap!" , Arrays .equals (output , decoded ));
172187 }
173188
174189 /**
175- * Test method does three tests on the supplied data:
176- * 1. encoded ---[DECODE]--> decoded
177- * 2. decoded ---[ENCODE]--> encoded
178- * 3. decoded ---[WRAP-WRAP-WRAP-etc...] --> decoded
190+ * Tests method does three tests on the supplied data: 1. encoded ---[DECODE]--> decoded 2. decoded ---[ENCODE]-->
191+ * encoded 3. decoded ---[WRAP-WRAP-WRAP-etc...] --> decoded
179192 * <p/>
180- * By "[WRAP-WRAP-WRAP-etc...]" we mean situation where the
181- * Base64InputStream wraps itself in encode and decode mode
193+ * By "[WRAP-WRAP-WRAP-etc...]" we mean situation where the Base64InputStream wraps itself in encode and decode mode
182194 * over and over again.
183- *
184- * @param encoded base64 encoded data
185- * @param decoded the data from above, but decoded
186- * @param chunkSize chunk size (line-length) of the base64 encoded data.
187- * @param seperator Line separator in the base64 encoded data.
188- * @throws Exception Usually signifies a bug in the Base64 commons-codec implementation.
195+ *
196+ * @param encoded
197+ * base64 encoded data
198+ * @param decoded
199+ * the data from above, but decoded
200+ * @param chunkSize
201+ * chunk size (line-length) of the base64 encoded data.
202+ * @param seperator
203+ * Line separator in the base64 encoded data.
204+ * @throws Exception
205+ * Usually signifies a bug in the Base64 commons-codec implementation.
189206 */
190- private void testByChunk (
191- byte [] encoded , byte [] decoded , int chunkSize , byte [] seperator
192- ) throws Exception {
207+ private void testByteByByte (byte [] encoded , byte [] decoded , int chunkSize , byte [] seperator ) throws Exception {
193208
194209 // Start with encode.
195210 InputStream in = new ByteArrayInputStream (decoded );
196211 in = new Base64InputStream (in , true , chunkSize , seperator );
197- byte [] output = Base64TestData .streamToBytes (in );
212+ byte [] output = new byte [encoded .length ];
213+ for (int i = 0 ; i < output .length ; i ++) {
214+ output [i ] = (byte ) in .read ();
215+ }
198216
199217 assertEquals ("EOF" , -1 , in .read ());
200218 assertEquals ("Still EOF" , -1 , in .read ());
@@ -203,22 +221,100 @@ private void testByChunk(
203221 // Now let's try decode.
204222 in = new ByteArrayInputStream (encoded );
205223 in = new Base64InputStream (in );
206- output = Base64TestData .streamToBytes (in );
224+ output = new byte [decoded .length ];
225+ for (int i = 0 ; i < output .length ; i ++) {
226+ output [i ] = (byte ) in .read ();
227+ }
207228
208229 assertEquals ("EOF" , -1 , in .read ());
209230 assertEquals ("Still EOF" , -1 , in .read ());
210231 assertTrue ("Streaming base64 decode" , Arrays .equals (output , decoded ));
211232
212- // I always wanted to do this! (wrap encoder with decoder etc etc).
233+ // I always wanted to do this! (wrap encoder with decoder etc etc).
213234 in = new ByteArrayInputStream (decoded );
214235 for (int i = 0 ; i < 10 ; i ++) {
215236 in = new Base64InputStream (in , true , chunkSize , seperator );
216237 in = new Base64InputStream (in , false );
217238 }
218- output = Base64TestData .streamToBytes (in );
239+ output = new byte [decoded .length ];
240+ for (int i = 0 ; i < output .length ; i ++) {
241+ output [i ] = (byte ) in .read ();
242+ }
219243
220244 assertEquals ("EOF" , -1 , in .read ());
221245 assertEquals ("Still EOF" , -1 , in .read ());
222246 assertTrue ("Streaming base64 wrap-wrap-wrap!" , Arrays .equals (output , decoded ));
223247 }
248+
249+ /**
250+ * Tests markSupported.
251+ *
252+ * @throws Exception
253+ */
254+ public void testMarkSupported () throws Exception {
255+ byte [] decoded = STRING_FIXTURE .getBytes (UTF_8_NAME );
256+ ByteArrayInputStream bin = new ByteArrayInputStream (decoded );
257+ Base64InputStream in = new Base64InputStream (bin , true , 4 , new byte []{0 , 0 , 0 });
258+ // Always returns false for now.
259+ assertFalse ("Base64InputStream.markSupported() is false" , in .markSupported ());
260+ }
261+
262+ /**
263+ * Tests read returning 0
264+ *
265+ * @throws Exception
266+ */
267+ public void testRead0 () throws Exception {
268+ byte [] decoded = STRING_FIXTURE .getBytes (UTF_8_NAME );
269+ byte [] buf = new byte [1024 ];
270+ int bytesRead = 0 ;
271+ ByteArrayInputStream bin = new ByteArrayInputStream (decoded );
272+ Base64InputStream in = new Base64InputStream (bin , true , 4 , new byte []{0 , 0 , 0 });
273+ bytesRead = in .read (buf , 0 , 0 );
274+ assertEquals ("Base64InputStream.read(buf, 0, 0) returns 0" , 0 , bytesRead );
275+ }
276+
277+ /**
278+ * Tests read with null.
279+ *
280+ * @throws Exception
281+ * for some failure scenarios.
282+ */
283+ public void testReadNull () throws Exception {
284+ byte [] decoded = STRING_FIXTURE .getBytes (UTF_8_NAME );
285+ ByteArrayInputStream bin = new ByteArrayInputStream (decoded );
286+ Base64InputStream in = new Base64InputStream (bin , true , 4 , new byte []{0 , 0 , 0 });
287+ try {
288+ in .read (null , 0 , 0 );
289+ fail ("Base64InputStream.read(null, 0, 0) to throw a NullPointerException" );
290+ } catch (NullPointerException e ) {
291+ // Expected
292+ }
293+ }
294+
295+ /**
296+ * Tests read throwing IndexOutOfBoundsException
297+ *
298+ * @throws Exception
299+ */
300+ public void testReadOutOfBounds () throws Exception {
301+ byte [] decoded = STRING_FIXTURE .getBytes (UTF_8_NAME );
302+ byte [] buf = new byte [1024 ];
303+ ByteArrayInputStream bin = new ByteArrayInputStream (decoded );
304+ Base64InputStream in = new Base64InputStream (bin , true , 4 , new byte []{0 , 0 , 0 });
305+
306+ try {
307+ in .read (buf , -1 , 0 );
308+ fail ("Expected Base64InputStream.read(buf, -1, 0) to throw IndexOutOfBoundsException" );
309+ } catch (IndexOutOfBoundsException e ) {
310+ // Expected
311+ }
312+
313+ try {
314+ in .read (buf , buf .length + 1 , 0 );
315+ fail ("Base64InputStream.read(buf, buf.length + 1, 0) throws IndexOutOfBoundsException" );
316+ } catch (IndexOutOfBoundsException e ) {
317+ // Expected
318+ }
319+ }
224320}
0 commit comments