1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.mina.filter.codec.textline;
21
22 import static org.junit.Assert.assertEquals;
23 import static org.junit.Assert.assertTrue;
24 import static org.junit.Assert.fail;
25
26 import java.nio.charset.Charset;
27 import java.nio.charset.CharsetEncoder;
28 import java.nio.charset.StandardCharsets;
29
30 import org.apache.mina.core.buffer.IoBuffer;
31 import org.apache.mina.filter.codec.ProtocolCodecSession;
32 import org.apache.mina.filter.codec.ProtocolDecoderOutput;
33 import org.apache.mina.filter.codec.RecoverableProtocolDecoderException;
34 import org.junit.Test;
35
36
37
38
39
40
41 public class TextLineDecoderTest {
42 @Test
43 public void testNormalDecode() throws Exception {
44 TextLineDecoder decoder = new TextLineDecoder(StandardCharsets.UTF_8, LineDelimiter.WINDOWS);
45
46 CharsetEncoder encoder = StandardCharsets.UTF_8.newEncoder();
47 ProtocolCodecSession session = new ProtocolCodecSession();
48 ProtocolDecoderOutput out = session.getDecoderOutput();
49 IoBuffer in = IoBuffer.allocate(16);
50
51
52 in.putString("ABC\r\n", encoder);
53 in.flip();
54 decoder.decode(session, in, out);
55 assertEquals(1, session.getDecoderOutputQueue().size());
56 assertEquals("ABC", session.getDecoderOutputQueue().poll());
57
58
59 in.clear();
60 in.putString("DEF", encoder);
61 in.flip();
62 decoder.decode(session, in, out);
63 assertEquals(0, session.getDecoderOutputQueue().size());
64 in.clear();
65 in.putString("GHI\r\n", encoder);
66 in.flip();
67 decoder.decode(session, in, out);
68 assertEquals(1, session.getDecoderOutputQueue().size());
69 assertEquals("DEFGHI", session.getDecoderOutputQueue().poll());
70
71
72 in.clear();
73 in.putString("JKL\r\nMNO\r\n", encoder);
74 in.flip();
75 decoder.decode(session, in, out);
76 assertEquals(2, session.getDecoderOutputQueue().size());
77 assertEquals("JKL", session.getDecoderOutputQueue().poll());
78 assertEquals("MNO", session.getDecoderOutputQueue().poll());
79
80
81 in.clear();
82 in.putString("ABC\r\r\n", encoder);
83 in.flip();
84 decoder.decode(session, in, out);
85 assertEquals(1, session.getDecoderOutputQueue().size());
86 assertEquals("ABC\r", session.getDecoderOutputQueue().poll());
87
88
89 decoder = new TextLineDecoder(StandardCharsets.UTF_8, new LineDelimiter("\n\n\n"));
90 in.clear();
91 in.putString("PQR\n", encoder);
92 in.flip();
93 decoder.decode(session, in, out);
94 assertEquals(0, session.getDecoderOutputQueue().size());
95 in.clear();
96 in.putString("\n", encoder);
97 in.flip();
98 decoder.decode(session, in, out);
99 assertEquals(0, session.getDecoderOutputQueue().size());
100 in.clear();
101 in.putString("\n", encoder);
102 in.flip();
103 decoder.decode(session, in, out);
104 assertEquals(1, session.getDecoderOutputQueue().size());
105 assertEquals("PQR", session.getDecoderOutputQueue().poll());
106
107
108 decoder = new TextLineDecoder(StandardCharsets.UTF_8, new LineDelimiter("\n\n\n"));
109 in.clear();
110 in.putString("PQR\n", encoder);
111 in.flip();
112 decoder.decode(session, in, out);
113 assertEquals(0, session.getDecoderOutputQueue().size());
114 in.clear();
115 in.putString("\n", encoder);
116 in.flip();
117 decoder.decode(session, in, out);
118 assertEquals(0, session.getDecoderOutputQueue().size());
119 in.clear();
120 in.putString("\nSTU\n\n\n", encoder);
121 in.flip();
122 decoder.decode(session, in, out);
123 assertEquals(2, session.getDecoderOutputQueue().size());
124 assertEquals("PQR", session.getDecoderOutputQueue().poll());
125 assertEquals("STU", session.getDecoderOutputQueue().poll());
126
127
128 decoder = new TextLineDecoder(StandardCharsets.UTF_8, new LineDelimiter("\n\n\n"));
129 in.clear();
130 in.putString("PQR\n", encoder);
131 in.flip();
132 decoder.decode(session, in, out);
133 assertEquals(0, session.getDecoderOutputQueue().size());
134 in.clear();
135 in.putString("X\n", encoder);
136 in.flip();
137 decoder.decode(session, in, out);
138 assertEquals(0, session.getDecoderOutputQueue().size());
139 in.clear();
140 in.putString("\n\nSTU\n\n\n", encoder);
141 in.flip();
142 decoder.decode(session, in, out);
143 assertEquals(2, session.getDecoderOutputQueue().size());
144 assertEquals("PQR\nX", session.getDecoderOutputQueue().poll());
145 assertEquals("STU", session.getDecoderOutputQueue().poll());
146 }
147
148 public void testAutoDecode() throws Exception {
149 TextLineDecoder decoder = new TextLineDecoder(StandardCharsets.UTF_8, LineDelimiter.AUTO);
150
151 CharsetEncoder encoder = StandardCharsets.UTF_8.newEncoder();
152 ProtocolCodecSession session = new ProtocolCodecSession();
153 ProtocolDecoderOutput out = session.getDecoderOutput();
154 IoBuffer in = IoBuffer.allocate(16);
155
156
157 in.putString("ABC\r\n", encoder);
158 in.flip();
159 decoder.decode(session, in, out);
160 assertEquals(1, session.getDecoderOutputQueue().size());
161 assertEquals("ABC", session.getDecoderOutputQueue().poll());
162
163
164 in.clear();
165 in.putString("DEF", encoder);
166 in.flip();
167 decoder.decode(session, in, out);
168 assertEquals(0, session.getDecoderOutputQueue().size());
169 in.clear();
170 in.putString("GHI\r\n", encoder);
171 in.flip();
172 decoder.decode(session, in, out);
173 assertEquals(1, session.getDecoderOutputQueue().size());
174 assertEquals("DEFGHI", session.getDecoderOutputQueue().poll());
175
176
177 in.clear();
178 in.putString("JKL\r\nMNO\r\n", encoder);
179 in.flip();
180 decoder.decode(session, in, out);
181 assertEquals(2, session.getDecoderOutputQueue().size());
182 assertEquals("JKL", session.getDecoderOutputQueue().poll());
183 assertEquals("MNO", session.getDecoderOutputQueue().poll());
184
185
186 in.clear();
187 in.putString("\n\n\n", encoder);
188 in.flip();
189 decoder.decode(session, in, out);
190 assertEquals(3, session.getDecoderOutputQueue().size());
191 assertEquals("", session.getDecoderOutputQueue().poll());
192 assertEquals("", session.getDecoderOutputQueue().poll());
193 assertEquals("", session.getDecoderOutputQueue().poll());
194
195
196 in.clear();
197 in.putString("PQR\r", encoder);
198 in.flip();
199 decoder.decode(session, in, out);
200 assertEquals(0, session.getDecoderOutputQueue().size());
201 in.clear();
202 in.putString("\r", encoder);
203 in.flip();
204 decoder.decode(session, in, out);
205 assertEquals(0, session.getDecoderOutputQueue().size());
206 in.clear();
207 in.putString("\n", encoder);
208 in.flip();
209 decoder.decode(session, in, out);
210 assertEquals(1, session.getDecoderOutputQueue().size());
211 assertEquals("PQR", session.getDecoderOutputQueue().poll());
212
213
214 in.clear();
215 in.putString("PQR\r", encoder);
216 in.flip();
217 decoder.decode(session, in, out);
218 assertEquals(0, session.getDecoderOutputQueue().size());
219 in.clear();
220 in.putString("\r", encoder);
221 in.flip();
222 decoder.decode(session, in, out);
223 assertEquals(0, session.getDecoderOutputQueue().size());
224 in.clear();
225 in.putString("\nSTU\r\r\n", encoder);
226 in.flip();
227 decoder.decode(session, in, out);
228 assertEquals(2, session.getDecoderOutputQueue().size());
229 assertEquals("PQR", session.getDecoderOutputQueue().poll());
230 assertEquals("STU", session.getDecoderOutputQueue().poll());
231
232
233 in.clear();
234 in.putString("PQR\r", encoder);
235 in.flip();
236 decoder.decode(session, in, out);
237 assertEquals(0, session.getDecoderOutputQueue().size());
238 in.clear();
239 in.putString("X\r", encoder);
240 in.flip();
241 decoder.decode(session, in, out);
242 assertEquals(0, session.getDecoderOutputQueue().size());
243 in.clear();
244 in.putString("\r\nSTU\r\r\n", encoder);
245 in.flip();
246 decoder.decode(session, in, out);
247 assertEquals(2, session.getDecoderOutputQueue().size());
248 assertEquals("PQR\rX", session.getDecoderOutputQueue().poll());
249 assertEquals("STU", session.getDecoderOutputQueue().poll());
250
251 in.clear();
252 String s = new String(new byte[] { 0, 77, 105, 110, 97 });
253 in.putString(s, encoder);
254 in.flip();
255 decoder.decode(session, in, out);
256 assertEquals(1, session.getDecoderOutputQueue().size());
257 assertEquals(s, session.getDecoderOutputQueue().poll());
258 }
259
260 public void testOverflow() throws Exception {
261 TextLineDecoder decoder = new TextLineDecoder(StandardCharsets.UTF_8, LineDelimiter.AUTO);
262 decoder.setMaxLineLength(3);
263
264 CharsetEncoder encoder = StandardCharsets.UTF_8.newEncoder();
265 ProtocolCodecSession session = new ProtocolCodecSession();
266 ProtocolDecoderOutput out = session.getDecoderOutput();
267 IoBuffer in = IoBuffer.allocate(16);
268
269
270
271 in.putString("A", encoder).flip().mark();
272 decoder.decode(session, in.reset().mark(), out);
273 assertEquals(0, session.getDecoderOutputQueue().size());
274 decoder.decode(session, in.reset().mark(), out);
275 assertEquals(0, session.getDecoderOutputQueue().size());
276 decoder.decode(session, in.reset().mark(), out);
277 assertEquals(0, session.getDecoderOutputQueue().size());
278 decoder.decode(session, in.reset().mark(), out);
279 assertEquals(0, session.getDecoderOutputQueue().size());
280
281 in.clear().putString("A\r\nB\r\n", encoder).flip();
282
283 try {
284 decoder.decode(session, in, out);
285 fail();
286 } catch (RecoverableProtocolDecoderException e) {
287
288 assertTrue(true);
289 }
290
291 decoder.decode(session, in, out);
292 assertEquals(1, session.getDecoderOutputQueue().size());
293 assertEquals("B", session.getDecoderOutputQueue().poll());
294
295
296 System.gc();
297 long oldFreeMemory = Runtime.getRuntime().freeMemory();
298 in = IoBuffer.allocate(1048576 * 16).sweep((byte) ' ').mark();
299
300 for (int i = 0; i < 10; i++) {
301 decoder.decode(session, in.reset().mark(), out);
302 assertEquals(0, session.getDecoderOutputQueue().size());
303
304
305 assertTrue(Runtime.getRuntime().freeMemory() - oldFreeMemory < 1048576);
306 }
307
308 in.clear().putString("C\r\nD\r\n", encoder).flip();
309 try {
310 decoder.decode(session, in, out);
311 fail();
312 } catch (RecoverableProtocolDecoderException e) {
313
314 assertTrue(true);
315 }
316
317 decoder.decode(session, in, out);
318 assertEquals(1, session.getDecoderOutputQueue().size());
319 assertEquals("D", session.getDecoderOutputQueue().poll());
320
321
322 assertTrue(Runtime.getRuntime().freeMemory() - oldFreeMemory < 1048576);
323 }
324
325 public void testSMTPDataBounds() throws Exception {
326 TextLineDecoder decoder = new TextLineDecoder(Charset.forName("ISO-8859-1"), new LineDelimiter("\r\n.\r\n"));
327
328 CharsetEncoder encoder = Charset.forName("ISO-8859-1").newEncoder();
329 ProtocolCodecSession session = new ProtocolCodecSession();
330 IoBuffer in = IoBuffer.allocate(16).setAutoExpand(true);
331
332 in.putString("\r\n", encoder).flip().mark();
333 decoder.decode(session, in.reset().mark(), session.getDecoderOutput());
334 assertEquals(0, session.getDecoderOutputQueue().size());
335 in.putString("Body\r\n.\r\n", encoder).flip().mark();
336 decoder.decode(session, in.reset().mark(), session.getDecoderOutput());
337 assertEquals(1, session.getDecoderOutputQueue().size());
338 assertEquals("\r\n\r\nBody", session.getDecoderOutputQueue().poll());
339 }
340 }