1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.fileupload2.core;
18
19 import static org.junit.jupiter.api.Assertions.assertArrayEquals;
20 import static org.junit.jupiter.api.Assertions.assertThrows;
21 import static org.junit.jupiter.api.Assertions.assertTrue;
22 import static org.junit.jupiter.api.Assertions.fail;
23
24 import java.io.ByteArrayOutputStream;
25 import java.io.IOException;
26 import java.nio.charset.StandardCharsets;
27
28 import org.junit.jupiter.api.Test;
29
30
31
32 public final class QuotedPrintableDecoderTestCase {
33
34 private static void assertEncoded(final String clearText, final String encoded) throws Exception {
35 final var expected = clearText.getBytes(StandardCharsets.US_ASCII);
36
37 final var out = new ByteArrayOutputStream(encoded.length());
38 final var encodedData = encoded.getBytes(StandardCharsets.US_ASCII);
39 QuotedPrintableDecoder.decode(encodedData, out);
40 final var actual = out.toByteArray();
41
42 assertArrayEquals(expected, actual);
43 }
44
45 private static void assertIOException(final String messageText, final String encoded) {
46 final var out = new ByteArrayOutputStream(encoded.length());
47 final var encodedData = encoded.getBytes(StandardCharsets.US_ASCII);
48 try {
49 QuotedPrintableDecoder.decode(encodedData, out);
50 fail("Expected IOException");
51 } catch (final IOException e) {
52 final var em = e.getMessage();
53 assertTrue(em.contains(messageText), "Expected to find " + messageText + " in '" + em + "'");
54 }
55 }
56
57 @Test
58 public void testBasicEncodeDecode() throws Exception {
59 assertEncoded("= Hello there =\r\n", "=3D Hello there =3D=0D=0A");
60 }
61
62 @Test
63 public void testEmptyDecode() throws Exception {
64 assertEncoded("", "");
65 }
66
67 @Test
68 public void testInvalidCharDecode() {
69 assertThrows(IOException.class, () -> assertEncoded("=\r\n", "=3D=XD=XA"));
70 }
71
72 @Test
73 public void testInvalidQuotedPrintableEncoding() throws Exception {
74 assertIOException("truncated escape sequence", "YWJjMTIzXy0uKn4hQCMkJV4mKCkre31cIlxcOzpgLC9bXQ==");
75 }
76
77 @Test
78 public void testInvalidSoftBreak1() throws Exception {
79 assertIOException("CR must be followed by LF", "=\r\r");
80 }
81
82 @Test
83 public void testInvalidSoftBreak2() throws Exception {
84 assertIOException("CR must be followed by LF", "=\rn");
85 }
86
87 @Test
88 public void testPlainDecode() throws Exception {
89
90
91 assertEncoded("The quick brown fox jumps over the lazy dog.", "The quick brown fox jumps over the lazy dog.");
92 }
93
94
95
96
97
98
99
100 @Test
101 public void testSoftLineBreakDecode() throws Exception {
102 assertEncoded("If you believe that truth=beauty, then surely mathematics is the most " + "beautiful branch of philosophy.",
103 "If you believe that truth=3Dbeauty, then " + "surely=20=\r\nmathematics is the most beautiful branch of philosophy.");
104 }
105
106 @Test
107 public void testUnsafeDecode() throws Exception {
108 assertEncoded("=\r\n", "=3D=0D=0A");
109 }
110
111 @Test
112 public void testUnsafeDecodeLowerCase() throws Exception {
113 assertEncoded("=\r\n", "=3d=0d=0a");
114 }
115
116 @Test
117 public void testTruncatedEscape() throws Exception {
118 assertIOException("truncated", "=1");
119 }
120
121 }