1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.codec.binary;
19
20 import static org.junit.jupiter.api.Assertions.assertArrayEquals;
21 import static org.junit.jupiter.api.Assertions.assertEquals;
22 import static org.junit.jupiter.api.Assertions.assertFalse;
23 import static org.junit.jupiter.api.Assertions.assertNotNull;
24 import static org.junit.jupiter.api.Assertions.assertThrows;
25 import static org.junit.jupiter.api.Assertions.assertTrue;
26
27 import java.io.ByteArrayInputStream;
28 import java.io.ByteArrayOutputStream;
29 import java.io.IOException;
30 import java.io.InputStream;
31
32 import org.apache.commons.codec.CodecPolicy;
33 import org.junit.jupiter.api.Test;
34
35
36
37
38 class Base32InputStreamTest {
39
40 private static final String ENCODED_FOO = "MZXW6===";
41
42 private static final byte[] CRLF = { (byte) '\r', (byte) '\n' };
43
44 private static final byte[] LF = { (byte) '\n' };
45
46 private static final String STRING_FIXTURE = "Hello World";
47
48
49
50
51
52
53
54 @Test
55 void testAvailable() throws Throwable {
56 final InputStream ins = new ByteArrayInputStream(StringUtils.getBytesIso8859_1(ENCODED_FOO));
57 try (Base32InputStream b32stream = new Base32InputStream(ins)) {
58 assertEquals(1, b32stream.available());
59 assertEquals(3, b32stream.skip(10));
60
61 assertEquals(0, b32stream.available());
62 assertEquals(-1, b32stream.read());
63 assertEquals(-1, b32stream.read());
64 assertEquals(0, b32stream.available());
65 }
66 }
67
68 private void testBase32EmptyInputStream(final int chuckSize) throws Exception {
69 final byte[] emptyEncoded = {};
70 final byte[] emptyDecoded = {};
71 testByteByByte(emptyEncoded, emptyDecoded, chuckSize, CRLF);
72 testByChunk(emptyEncoded, emptyDecoded, chuckSize, CRLF);
73 }
74
75
76
77
78
79
80
81 @Test
82 void testBase32EmptyInputStreamMimeChuckSize() throws Exception {
83 testBase32EmptyInputStream(BaseNCodec.MIME_CHUNK_SIZE);
84 }
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158 @Test
159 void testBase32EmptyInputStreamPemChuckSize() throws Exception {
160 testBase32EmptyInputStream(BaseNCodec.PEM_CHUNK_SIZE);
161 }
162
163
164
165
166
167
168
169 @Test
170 void testBase32InputStreamByChunk() throws Exception {
171
172 byte[] encoded = StringUtils.getBytesUtf8(Base32TestData.BASE32_FIXTURE);
173 byte[] decoded = StringUtils.getBytesUtf8(Base32TestData.STRING_FIXTURE);
174 testByChunk(encoded, decoded, BaseNCodec.MIME_CHUNK_SIZE, CRLF);
175
176
177 encoded = StringUtils.getBytesUtf8("AA======\r\n");
178 decoded = new byte[] { (byte) 0 };
179 testByChunk(encoded, decoded, BaseNCodec.MIME_CHUNK_SIZE, CRLF);
180
181
182
183
184
185
186
187
188
189
190
191
192
193 final BaseNCodec codec = new Base32();
194 for (int i = 0; i <= 150; i++) {
195 final byte[][] randomData = BaseNTestData.randomData(codec, i);
196 encoded = randomData[1];
197 decoded = randomData[0];
198 testByChunk(encoded, decoded, 0, LF);
199 }
200 }
201
202
203
204
205
206
207
208 @Test
209 void testBase32InputStreamByteByByte() throws Exception {
210
211 byte[] encoded = StringUtils.getBytesUtf8(Base32TestData.BASE32_FIXTURE);
212 byte[] decoded = StringUtils.getBytesUtf8(Base32TestData.STRING_FIXTURE);
213 testByteByByte(encoded, decoded, BaseNCodec.MIME_CHUNK_SIZE, CRLF);
214
215
216 encoded = StringUtils.getBytesUtf8("AA======\r\n");
217 decoded = new byte[] { (byte) 0 };
218 testByteByByte(encoded, decoded, BaseNCodec.MIME_CHUNK_SIZE, CRLF);
219
220
221
222
223
224
225
226
227 final BaseNCodec codec = new Base32();
228 for (int i = 0; i <= 150; i++) {
229 final byte[][] randomData = BaseNTestData.randomData(codec, i);
230 encoded = randomData[1];
231 decoded = randomData[0];
232 testByteByByte(encoded, decoded, 0, LF);
233 }
234 }
235
236 @Test
237 void testBuilder() {
238 assertNotNull(Base32InputStream.builder().getBaseNCodec());
239 }
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259 private void testByChunk(final byte[] encoded, final byte[] decoded, final int chunkSize, final byte[] separator) throws Exception {
260
261 try (InputStream in = new Base32InputStream(new ByteArrayInputStream(decoded), true, chunkSize, separator)) {
262 final byte[] output = BaseNTestData.streamToBytes(in);
263 assertEquals(-1, in.read(), "EOF");
264 assertEquals(-1, in.read(), "Still EOF");
265 assertArrayEquals(encoded, output, "Streaming base32 encode");
266 }
267
268 try (InputStream in = new Base32InputStream(new ByteArrayInputStream(encoded))) {
269 final byte[] output = BaseNTestData.streamToBytes(in);
270
271 assertEquals(-1, in.read(), "EOF");
272 assertEquals(-1, in.read(), "Still EOF");
273 assertArrayEquals(decoded, output, "Streaming base32 decode");
274 }
275
276 InputStream in = new ByteArrayInputStream(decoded);
277 for (int i = 0; i < 10; i++) {
278 in = new Base32InputStream(in, true, chunkSize, separator);
279 in = new Base32InputStream(in, false);
280 }
281 final byte[] output = BaseNTestData.streamToBytes(in);
282 assertEquals(-1, in.read(), "EOF");
283 assertEquals(-1, in.read(), "Still EOF");
284 assertArrayEquals(decoded, output, "Streaming base32 wrap-wrap-wrap!");
285 in.close();
286 }
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306 private void testByteByByte(final byte[] encoded, final byte[] decoded, final int chunkSize, final byte[] separator) throws Exception {
307
308
309 InputStream in;
310 in = new Base32InputStream(new ByteArrayInputStream(decoded), true, chunkSize, separator);
311 byte[] output = new byte[encoded.length];
312 for (int i = 0; i < output.length; i++) {
313 output[i] = (byte) in.read();
314 }
315
316 assertEquals(-1, in.read(), "EOF");
317 assertEquals(-1, in.read(), "Still EOF");
318 assertArrayEquals(encoded, output, "Streaming base32 encode");
319
320 in.close();
321
322
323 in = new Base32InputStream(new ByteArrayInputStream(encoded));
324 output = new byte[decoded.length];
325 for (int i = 0; i < output.length; i++) {
326 output[i] = (byte) in.read();
327 }
328
329 assertEquals(-1, in.read(), "EOF");
330 assertEquals(-1, in.read(), "Still EOF");
331 assertArrayEquals(decoded, output, "Streaming base32 decode");
332
333 in.close();
334
335
336 in = new ByteArrayInputStream(decoded);
337 for (int i = 0; i < 10; i++) {
338 in = new Base32InputStream(in, true, chunkSize, separator);
339 in = new Base32InputStream(in, false);
340 }
341 output = new byte[decoded.length];
342 for (int i = 0; i < output.length; i++) {
343 output[i] = (byte) in.read();
344 }
345
346 assertEquals(-1, in.read(), "EOF");
347 assertEquals(-1, in.read(), "Still EOF");
348 assertArrayEquals(decoded, output, "Streaming base32 wrap-wrap-wrap!");
349 }
350
351
352
353
354 @Test
355 void testCodec105() throws IOException {
356 try (Base32InputStream in = new Base32InputStream(new Codec105ErrorInputStream(), true, 0, null)) {
357 for (int i = 0; i < 5; i++) {
358 in.read();
359 }
360 }
361 }
362
363
364
365
366 @Test
367 void testCodec130() throws IOException {
368 final ByteArrayOutputStream bos = new ByteArrayOutputStream();
369 try (Base32OutputStream base32os = new Base32OutputStream(bos)) {
370 base32os.write(StringUtils.getBytesUtf8(STRING_FIXTURE));
371 }
372
373 final ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
374 final Base32InputStream ins = new Base32InputStream(bis);
375
376
377 assertEquals(1, ins.skip(1));
378 final byte[] decodedBytes = BaseNTestData.streamToBytes(ins, new byte[64]);
379 final String str = StringUtils.newStringUtf8(decodedBytes);
380
381 assertEquals(STRING_FIXTURE.substring(1), str);
382 }
383
384
385
386
387
388
389
390 @Test
391 void testMarkSupported() throws Exception {
392 final byte[] decoded = StringUtils.getBytesUtf8(Base32TestData.STRING_FIXTURE);
393 final ByteArrayInputStream bin = new ByteArrayInputStream(decoded);
394 try (Base32InputStream in = new Base32InputStream(bin, true, 4, new byte[] { 0, 0, 0 })) {
395
396 assertFalse(in.markSupported(), "Base32InputStream.markSupported() is false");
397 }
398 }
399
400
401
402
403
404
405
406 @Test
407 void testRead0() throws Exception {
408 final byte[] decoded = StringUtils.getBytesUtf8(Base32TestData.STRING_FIXTURE);
409 final byte[] buf = new byte[1024];
410 int bytesRead = 0;
411 final ByteArrayInputStream bin = new ByteArrayInputStream(decoded);
412 try (Base32InputStream in = new Base32InputStream(bin, true, 4, new byte[] { 0, 0, 0 })) {
413 bytesRead = in.read(buf, 0, 0);
414 assertEquals(0, bytesRead, "Base32InputStream.read(buf, 0, 0) returns 0");
415 }
416 }
417
418
419
420
421
422
423
424 @Test
425 void testReadNull() throws Exception {
426 final byte[] decoded = StringUtils.getBytesUtf8(Base32TestData.STRING_FIXTURE);
427 final ByteArrayInputStream bin = new ByteArrayInputStream(decoded);
428 try (Base32InputStream in = new Base32InputStream(bin, true, 4, new byte[] {0, 0, 0})) {
429 assertThrows(NullPointerException.class, () -> in.read(null, 0, 0));
430 }
431 }
432
433
434
435
436
437
438
439 @Test
440 void testReadOutOfBounds() throws Exception {
441 final byte[] decoded = StringUtils.getBytesUtf8(Base32TestData.STRING_FIXTURE);
442 final byte[] buf = new byte[1024];
443 final ByteArrayInputStream bin = new ByteArrayInputStream(decoded);
444 try (Base32InputStream in = new Base32InputStream(bin, true, 4, new byte[] { 0, 0, 0 })) {
445 assertThrows(IndexOutOfBoundsException.class, () -> in.read(buf, -1, 0), "Base32InputStream.read(buf, -1, 0)");
446 assertThrows(IndexOutOfBoundsException.class, () -> in.read(buf, 0, -1), "Base32InputStream.read(buf, 0, -1)");
447 assertThrows(IndexOutOfBoundsException.class, () -> in.read(buf, buf.length + 1, 0), "Base32InputStream.read(buf, buf.length + 1, 0)");
448 assertThrows(IndexOutOfBoundsException.class, () -> in.read(buf, buf.length - 1, 2), "Base32InputStream.read(buf, buf.length - 1, 2)");
449 }
450 }
451
452
453
454
455
456
457
458 @Test
459 void testSkipBig() throws Throwable {
460 final InputStream ins = new ByteArrayInputStream(StringUtils.getBytesIso8859_1(ENCODED_FOO));
461 try (Base32InputStream b32stream = new Base32InputStream(ins)) {
462 assertEquals(3, b32stream.skip(1024));
463
464 assertEquals(-1, b32stream.read());
465 assertEquals(-1, b32stream.read());
466 }
467 }
468
469
470
471
472
473
474
475 @Test
476 void testSkipNone() throws Throwable {
477 final InputStream ins = new ByteArrayInputStream(StringUtils.getBytesIso8859_1(ENCODED_FOO));
478 try (Base32InputStream b32stream = new Base32InputStream(ins)) {
479 final byte[] actualBytes = new byte[6];
480 assertEquals(0, b32stream.skip(0));
481 b32stream.read(actualBytes, 0, actualBytes.length);
482 assertArrayEquals(actualBytes, new byte[] { 102, 111, 111, 0, 0, 0 });
483
484 assertEquals(-1, b32stream.read());
485 }
486 }
487
488
489
490
491
492
493
494 @Test
495 void testSkipPastEnd() throws Throwable {
496 final InputStream ins = new ByteArrayInputStream(StringUtils.getBytesIso8859_1(ENCODED_FOO));
497 try (Base32InputStream b32stream = new Base32InputStream(ins)) {
498
499 assertEquals(3, b32stream.skip(10));
500
501 assertEquals(-1, b32stream.read());
502 assertEquals(-1, b32stream.read());
503 }
504 }
505
506
507
508
509
510
511
512 @Test
513 void testSkipToEnd() throws Throwable {
514 final InputStream ins = new ByteArrayInputStream(StringUtils.getBytesIso8859_1(ENCODED_FOO));
515 try (Base32InputStream b32stream = new Base32InputStream(ins)) {
516
517 assertEquals(3, b32stream.skip(3));
518
519 assertEquals(-1, b32stream.read());
520 assertEquals(-1, b32stream.read());
521 }
522 }
523
524
525
526
527
528
529
530 @Test
531 void testSkipWrongArgument() throws Throwable {
532 final InputStream ins = new ByteArrayInputStream(StringUtils.getBytesIso8859_1(ENCODED_FOO));
533 try (Base32InputStream b32stream = new Base32InputStream(ins)) {
534 assertThrows(IllegalArgumentException.class, () -> b32stream.skip(-10));
535 }
536 }
537
538
539
540
541
542
543
544 @Test
545 void testStrictDecoding() throws Exception {
546 for (final String s : Base32Test.BASE32_IMPOSSIBLE_CASES) {
547 final byte[] encoded = StringUtils.getBytesUtf8(s);
548 final Base32InputStream in = new Base32InputStream(new ByteArrayInputStream(encoded), false);
549
550 assertFalse(in.isStrictDecoding());
551 BaseNTestData.streamToBytes(in);
552
553 final Base32InputStream in2 = new Base32InputStream(new ByteArrayInputStream(encoded), false, 0, null, CodecPolicy.STRICT);
554 assertTrue(in2.isStrictDecoding());
555 assertThrows(IllegalArgumentException.class, () -> BaseNTestData.streamToBytes(in2));
556
557 try (Base32InputStream in3 = Base32InputStream.builder()
558 .setInputStream(new ByteArrayInputStream(encoded))
559 .setEncode(false)
560 .setBaseNCodec(Base32.builder().setLineLength(0).setLineSeparator(null).setDecodingPolicy(CodecPolicy.STRICT).get())
561 .get()) {
562 assertTrue(in3.isStrictDecoding());
563 assertThrows(IllegalArgumentException.class, () -> BaseNTestData.streamToBytes(in3));
564 }
565 }
566 }
567 }