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.assertFalse;
22 import static org.junit.jupiter.api.Assertions.assertNotNull;
23 import static org.junit.jupiter.api.Assertions.assertThrows;
24 import static org.junit.jupiter.api.Assertions.assertTrue;
25
26 import java.io.ByteArrayOutputStream;
27 import java.io.IOException;
28 import java.io.OutputStream;
29
30 import org.apache.commons.codec.CodecPolicy;
31 import org.junit.jupiter.api.Test;
32
33
34
35
36 class Base32OutputStreamTest extends AbstractBaseNOutputStreamTest {
37
38 private static final byte[] CR_LF = {(byte) '\r', (byte) '\n'};
39
40 private static final byte[] LF = {(byte) '\n'};
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65 @Override
66 OutputStream newOutputStream() {
67 return new Base32OutputStream(new ByteArrayOutputStream());
68 }
69
70 private void testBase32EmptyOutputStream(final int chunkSize) throws Exception {
71 final byte[] emptyEncoded = {};
72 final byte[] emptyDecoded = {};
73 testByteByByte(emptyEncoded, emptyDecoded, chunkSize, CR_LF);
74 testByChunk(emptyEncoded, emptyDecoded, chunkSize, CR_LF);
75 }
76
77
78
79
80
81
82
83 @Test
84 void testBase32EmptyOutputStreamMimeChunkSize() throws Exception {
85 testBase32EmptyOutputStream(BaseNCodec.MIME_CHUNK_SIZE);
86 }
87
88
89
90
91
92
93
94 @Test
95 void testBase32EmptyOutputStreamPemChunkSize() throws Exception {
96 testBase32EmptyOutputStream(BaseNCodec.PEM_CHUNK_SIZE);
97 }
98
99
100
101
102
103
104
105 @Test
106 void testBase32OutputStreamByChunk() throws Exception {
107
108 byte[] encoded = StringUtils.getBytesUtf8(Base32TestData.BASE32_FIXTURE);
109 byte[] decoded = StringUtils.getBytesUtf8(Base32TestData.STRING_FIXTURE);
110 testByChunk(encoded, decoded, BaseNCodec.MIME_CHUNK_SIZE, CR_LF);
111
112
113
114
115
116
117
118
119
120
121
122
123
124 final BaseNCodec codec = new Base32();
125 for (int i = 0; i <= 150; i++) {
126 final byte[][] randomData = BaseNTestData.randomData(codec, i);
127 encoded = randomData[1];
128 decoded = randomData[0];
129 testByChunk(encoded, decoded, 0, LF);
130 }
131 }
132
133
134
135
136
137
138
139 @Test
140 void testBase32OutputStreamByteByByte() throws Exception {
141
142 byte[] encoded = StringUtils.getBytesUtf8(Base32TestData.BASE32_FIXTURE);
143 byte[] decoded = StringUtils.getBytesUtf8(Base32TestData.STRING_FIXTURE);
144 testByteByByte(encoded, decoded, 76, CR_LF);
145
146
147
148
149
150
151
152
153
154
155
156
157
158 final BaseNCodec codec = new Base32();
159 for (int i = 0; i <= 150; i++) {
160 final byte[][] randomData = BaseNTestData.randomData(codec, i);
161 encoded = randomData[1];
162 decoded = randomData[0];
163 testByteByByte(encoded, decoded, 0, LF);
164 }
165 }
166
167 @Test
168 void testBuilder() {
169 assertNotNull(Base32OutputStream.builder().getBaseNCodec());
170 }
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190 private void testByChunk(final byte[] encoded, final byte[] decoded, final int chunkSize, final byte[] separator) throws Exception {
191
192
193 ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
194 try (OutputStream out = new Base32OutputStream(byteOut, true, chunkSize, separator)) {
195 out.write(decoded);
196 }
197 byte[] output = byteOut.toByteArray();
198 assertArrayEquals(encoded, output, "Streaming chunked Base32 encode");
199
200
201 byteOut = new ByteArrayOutputStream();
202 try (OutputStream out = new Base32OutputStream(byteOut, false)) {
203 out.write(encoded);
204 }
205 output = byteOut.toByteArray();
206 assertArrayEquals(decoded, output, "Streaming chunked Base32 decode");
207
208
209 byteOut = new ByteArrayOutputStream();
210 OutputStream out = byteOut;
211 for (int i = 0; i < 10; i++) {
212 out = new Base32OutputStream(out, false);
213 out = new Base32OutputStream(out, true, chunkSize, separator);
214 }
215 out.write(decoded);
216 out.close();
217 output = byteOut.toByteArray();
218
219 assertArrayEquals(decoded, byteOut.toByteArray(), "Streaming chunked Base32 wrap-wrap-wrap!");
220 }
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240 private void testByteByByte(final byte[] encoded, final byte[] decoded, final int chunkSize, final byte[] separator) throws Exception {
241
242
243 ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
244 try (OutputStream out = new Base32OutputStream(byteOut, true, chunkSize, separator)) {
245 for (final byte element : decoded) {
246 out.write(element);
247 }
248 }
249 byte[] output = byteOut.toByteArray();
250 assertArrayEquals(encoded, output, "Streaming byte-by-byte Base32 encode");
251
252
253 byteOut = new ByteArrayOutputStream();
254 try (OutputStream out = new Base32OutputStream(byteOut, false)) {
255 for (final byte element : encoded) {
256 out.write(element);
257 }
258 }
259 output = byteOut.toByteArray();
260 assertArrayEquals(decoded, output, "Streaming byte-by-byte Base32 decode");
261
262
263 byteOut = new ByteArrayOutputStream();
264 try (OutputStream out = new Base32OutputStream(byteOut, false)) {
265 for (final byte element : encoded) {
266 out.write(element);
267 out.flush();
268 }
269 }
270 output = byteOut.toByteArray();
271 assertArrayEquals(decoded, output, "Streaming byte-by-byte flush() Base32 decode");
272
273
274 byteOut = new ByteArrayOutputStream();
275 OutputStream out = byteOut;
276 for (int i = 0; i < 10; i++) {
277 out = new Base32OutputStream(out, false);
278 out = new Base32OutputStream(out, true, chunkSize, separator);
279 }
280 for (final byte element : decoded) {
281 out.write(element);
282 }
283 out.close();
284 output = byteOut.toByteArray();
285
286 assertArrayEquals(decoded, output, "Streaming byte-by-byte Base32 wrap-wrap-wrap!");
287 }
288
289
290
291
292
293
294
295 @Test
296 void testStrictDecoding() throws Exception {
297 for (final String s : Base32Test.BASE32_IMPOSSIBLE_CASES) {
298 final byte[] encoded = StringUtils.getBytesUtf8(s);
299 ByteArrayOutputStream bout = new ByteArrayOutputStream();
300 try (Base32OutputStream out = new Base32OutputStream(bout, false)) {
301
302 assertFalse(out.isStrictDecoding());
303 out.write(encoded);
304 out.close();
305 assertTrue(bout.size() > 0);
306
307
308 bout = new ByteArrayOutputStream();
309 try (Base32OutputStream out2 = new Base32OutputStream(bout, false, 0, null, CodecPolicy.STRICT)) {
310 assertTrue(out2.isStrictDecoding());
311 final IOException ioe = assertThrows(IOException.class, () -> {
312 out2.write(encoded);
313 out2.eof();
314 });
315 assertTrue(ioe.getCause() instanceof IllegalArgumentException);
316 }
317 try (Base32OutputStream out2 = Base32OutputStream.builder()
318 .setOutputStream(bout).setEncode(false)
319 .setBaseNCodec(Base32.builder().setLineLength(0).setLineSeparator(null).setDecodingPolicy(CodecPolicy.STRICT).get())
320 .get()) {
321 assertTrue(out2.isStrictDecoding());
322 final IOException ioe = assertThrows(IOException.class, () -> {
323 out2.write(encoded);
324 out2.eof();
325 });
326 assertTrue(ioe.getCause() instanceof IllegalArgumentException);
327 }
328 try (Base32OutputStream out2 = Base32OutputStream.builder()
329 .setOutputStream(bout).setEncode(false)
330 .setBaseNCodec(Base32.builder().setDecodingPolicy(CodecPolicy.STRICT).get())
331 .get()) {
332 assertTrue(out2.isStrictDecoding());
333 final IOException ioe = assertThrows(IOException.class, () -> {
334 out2.write(encoded);
335 out2.eof();
336 });
337 assertTrue(ioe.getCause() instanceof IllegalArgumentException);
338 }
339 }
340 }
341 }
342
343
344
345
346
347
348
349 @Test
350 void testWriteOutOfBounds() throws Exception {
351 final byte[] buf = new byte[1024];
352 final ByteArrayOutputStream bout = new ByteArrayOutputStream();
353 try (Base32OutputStream out = new Base32OutputStream(bout)) {
354 assertThrows(IndexOutOfBoundsException.class, () -> out.write(buf, -1, 1), "Base32OutputStream.write(buf, -1, 1)");
355 assertThrows(IndexOutOfBoundsException.class, () -> out.write(buf, 1, -1), "Base32OutputStream.write(buf, 1, -1)");
356 assertThrows(IndexOutOfBoundsException.class, () -> out.write(buf, buf.length + 1, 0), "Base32OutputStream.write(buf, buf, buf.length + 1, 0)");
357 assertThrows(IndexOutOfBoundsException.class, () -> out.write(buf, buf.length - 1, 2), "Base32OutputStream.write(buf, buf, buf.length - 1, 2)");
358 }
359 }
360
361
362
363
364
365
366
367 @Test
368 void testWriteToNullCoverage() throws Exception {
369 final ByteArrayOutputStream bout = new ByteArrayOutputStream();
370 try (Base32OutputStream out = new Base32OutputStream(bout)) {
371 assertThrows(NullPointerException.class, () -> out.write(null, 0, 0));
372 }
373 }
374 }