1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.lang3;
18
19 import static org.junit.jupiter.api.Assertions.assertEquals;
20 import static org.junit.jupiter.api.Assertions.assertFalse;
21 import static org.junit.jupiter.api.Assertions.assertNotNull;
22 import static org.junit.jupiter.api.Assertions.assertNull;
23 import static org.junit.jupiter.api.Assertions.assertThrows;
24 import static org.junit.jupiter.api.Assertions.assertTrue;
25
26 import java.io.IOException;
27 import java.io.StringWriter;
28 import java.lang.reflect.Constructor;
29 import java.lang.reflect.Modifier;
30 import java.nio.charset.StandardCharsets;
31 import java.nio.file.Files;
32 import java.nio.file.Paths;
33
34 import org.apache.commons.lang3.text.translate.CharSequenceTranslator;
35 import org.apache.commons.lang3.text.translate.NumericEntityEscaper;
36 import org.junit.jupiter.api.Test;
37
38
39
40
41 @Deprecated
42 public class StringEscapeUtilsTest extends AbstractLangTest {
43 private static final String FOO = "foo";
44
45
46 private static final String[][] HTML_ESCAPES = {
47 {"no escaping", "plain text", "plain text"},
48 {"no escaping", "plain text", "plain text"},
49 {"empty string", "", ""},
50 {"null", null, null},
51 {"ampersand", "bread & butter", "bread & butter"},
52 {"quotes", ""bread" & butter", "\"bread\" & butter"},
53 {"final character only", "greater than >", "greater than >"},
54 {"first character only", "< less than", "< less than"},
55 {"apostrophe", "Huntington's chorea", "Huntington's chorea"},
56 {"languages", "English,Français,\u65E5\u672C\u8A9E (nihongo)", "English,Fran\u00E7ais,\u65E5\u672C\u8A9E (nihongo)"},
57 {"8-bit ascii shouldn't number-escape", "\u0080\u009F", "\u0080\u009F"},
58 };
59
60 private void assertEscapeJava(final String escaped, final String original) throws IOException {
61 assertEscapeJava(null, escaped, original);
62 }
63
64 private void assertEscapeJava(String message, final String expected, final String original) throws IOException {
65 final String converted = StringEscapeUtils.escapeJava(original);
66 message = "escapeJava(String) failed" + (message == null ? "" : (": " + message));
67 assertEquals(expected, converted, message);
68
69 final StringWriter writer = new StringWriter();
70 StringEscapeUtils.ESCAPE_JAVA.translate(original, writer);
71 assertEquals(expected, writer.toString());
72 }
73
74 private void assertUnescapeJava(final String unescaped, final String original) throws IOException {
75 assertUnescapeJava(null, unescaped, original);
76 }
77
78 private void assertUnescapeJava(final String message, final String unescaped, final String original) throws IOException {
79 final String expected = unescaped;
80 final String actual = StringEscapeUtils.unescapeJava(original);
81
82 assertEquals(expected, actual,
83 "unescape(String) failed" +
84 (message == null ? "" : (": " + message)) +
85 ": expected '" + StringEscapeUtils.escapeJava(expected) +
86
87 "' actual '" + StringEscapeUtils.escapeJava(actual) + "'");
88
89 final StringWriter writer = new StringWriter();
90 StringEscapeUtils.UNESCAPE_JAVA.translate(original, writer);
91 assertEquals(unescaped, writer.toString());
92
93 }
94
95 private void checkCsvEscapeWriter(final String expected, final String value) throws IOException {
96 final StringWriter writer = new StringWriter();
97 StringEscapeUtils.ESCAPE_CSV.translate(value, writer);
98 assertEquals(expected, writer.toString());
99 }
100
101 private void checkCsvUnescapeWriter(final String expected, final String value) throws IOException {
102 final StringWriter writer = new StringWriter();
103 StringEscapeUtils.UNESCAPE_CSV.translate(value, writer);
104 assertEquals(expected, writer.toString());
105 }
106
107 @Test
108 public void testConstructor() {
109 assertNotNull(new StringEscapeUtils());
110 final Constructor<?>[] cons = StringEscapeUtils.class.getDeclaredConstructors();
111 assertEquals(1, cons.length);
112 assertTrue(Modifier.isPublic(cons[0].getModifiers()));
113 assertTrue(Modifier.isPublic(StringEscapeUtils.class.getModifiers()));
114 assertFalse(Modifier.isFinal(StringEscapeUtils.class.getModifiers()));
115 }
116
117 @Test
118 public void testEscapeCsvIllegalStateException() {
119 final StringWriter writer = new StringWriter();
120 assertThrows(IllegalStateException.class, () -> StringEscapeUtils.ESCAPE_CSV.translate("foo", -1, writer));
121 }
122
123 @Test
124 public void testEscapeCsvString() {
125 assertEquals("foo.bar", StringEscapeUtils.escapeCsv("foo.bar"));
126 assertEquals("\"foo,bar\"", StringEscapeUtils.escapeCsv("foo,bar"));
127 assertEquals("\"foo\nbar\"", StringEscapeUtils.escapeCsv("foo\nbar"));
128 assertEquals("\"foo\rbar\"", StringEscapeUtils.escapeCsv("foo\rbar"));
129 assertEquals("\"foo\"\"bar\"", StringEscapeUtils.escapeCsv("foo\"bar"));
130 assertEquals("foo\uD84C\uDFB4bar", StringEscapeUtils.escapeCsv("foo\uD84C\uDFB4bar"));
131 assertEquals("", StringEscapeUtils.escapeCsv(""));
132 assertNull(StringEscapeUtils.escapeCsv(null));
133 }
134
135
136 @Test
137 public void testEscapeCsvWriter() throws Exception {
138 checkCsvEscapeWriter("foo.bar", "foo.bar");
139 checkCsvEscapeWriter("\"foo,bar\"", "foo,bar");
140 checkCsvEscapeWriter("\"foo\nbar\"", "foo\nbar");
141 checkCsvEscapeWriter("\"foo\rbar\"", "foo\rbar");
142 checkCsvEscapeWriter("\"foo\"\"bar\"", "foo\"bar");
143 checkCsvEscapeWriter("foo\uD84C\uDFB4bar", "foo\uD84C\uDFB4bar");
144 checkCsvEscapeWriter("", null);
145 checkCsvEscapeWriter("", "");
146 }
147
148 @Test
149 public void testEscapeEcmaScript() {
150 assertNull(StringEscapeUtils.escapeEcmaScript(null));
151 assertThrows(NullPointerException.class, () -> StringEscapeUtils.ESCAPE_ECMASCRIPT.translate(null, null));
152 assertThrows(NullPointerException.class, () -> StringEscapeUtils.ESCAPE_ECMASCRIPT.translate("", null));
153
154 assertEquals("He didn\\'t say, \\\"stop!\\\"", StringEscapeUtils.escapeEcmaScript("He didn't say, \"stop!\""));
155 assertEquals("document.getElementById(\\\"test\\\").value = \\'<script>alert(\\'aaa\\');<\\/script>\\';",
156 StringEscapeUtils.escapeEcmaScript("document.getElementById(\"test\").value = '<script>alert('aaa');</script>';"));
157 }
158
159
160
161
162 @Test
163 public void testEscapeHiragana() {
164
165 final String original = "\u304B\u304C\u3068";
166 final String escaped = StringEscapeUtils.escapeHtml4(original);
167 assertEquals(original, escaped,
168 "Hiragana character Unicode behavior should not be being escaped by escapeHtml4");
169
170 final String unescaped = StringEscapeUtils.unescapeHtml4( escaped );
171
172 assertEquals(escaped, unescaped, "Hiragana character Unicode behavior has changed - expected no unescaping");
173 }
174
175 @Test
176 public void testEscapeHtml() throws IOException {
177 for (final String[] element : HTML_ESCAPES) {
178 final String message = element[0];
179 final String expected = element[1];
180 final String original = element[2];
181 assertEquals(expected, StringEscapeUtils.escapeHtml4(original), message);
182 final StringWriter sw = new StringWriter();
183 StringEscapeUtils.ESCAPE_HTML4.translate(original, sw);
184 final String actual = original == null ? null : sw.toString();
185 assertEquals(expected, actual, message);
186 }
187 }
188
189
190
191
192 @Test
193 public void testEscapeHtmlHighUnicode() {
194
195
196
197
198 final byte[] data = { (byte) 0xF0, (byte) 0x9D, (byte) 0x8D, (byte) 0xA2 };
199
200 final String original = new String(data, StandardCharsets.UTF_8);
201
202 final String escaped = StringEscapeUtils.escapeHtml4( original );
203 assertEquals(original, escaped, "High Unicode should not have been escaped");
204
205 final String unescaped = StringEscapeUtils.unescapeHtml4( escaped );
206 assertEquals(original, unescaped, "High Unicode should have been unchanged");
207
208
209
210
211 }
212
213 @Test
214 public void testEscapeHtmlVersions() {
215 assertEquals("Β", StringEscapeUtils.escapeHtml4("\u0392"));
216 assertEquals("\u0392", StringEscapeUtils.unescapeHtml4("Β"));
217
218
219 }
220
221 @Test
222 public void testEscapeJava() throws IOException {
223 assertNull(StringEscapeUtils.escapeJava(null));
224 assertThrows(NullPointerException.class, () -> StringEscapeUtils.ESCAPE_JAVA.translate(null, null));
225 assertThrows(NullPointerException.class, () -> StringEscapeUtils.ESCAPE_JAVA.translate("", null));
226
227 assertEscapeJava("empty string", "", "");
228 assertEscapeJava(FOO, FOO);
229 assertEscapeJava("tab", "\\t", "\t");
230 assertEscapeJava("backslash", "\\\\", "\\");
231 assertEscapeJava("single quote should not be escaped", "'", "'");
232 assertEscapeJava("\\\\\\b\\t\\r", "\\\b\t\r");
233 assertEscapeJava("\\u1234", "\u1234");
234 assertEscapeJava("\\u0234", "\u0234");
235 assertEscapeJava("\\u00EF", "\u00ef");
236 assertEscapeJava("\\u0001", "\u0001");
237 assertEscapeJava("Should use capitalized Unicode hex", "\\uABCD", "\uabcd");
238
239 assertEscapeJava("He didn't say, \\\"stop!\\\"",
240 "He didn't say, \"stop!\"");
241 assertEscapeJava("non-breaking space", "This space is non-breaking:" + "\\u00A0",
242 "This space is non-breaking:\u00a0");
243 assertEscapeJava("\\uABCD\\u1234\\u012C",
244 "\uABCD\u1234\u012C");
245 }
246
247
248
249
250 @Test
251 public void testEscapeJavaWithSlash() {
252 final String input = "String with a slash (/) in it";
253
254 final String expected = input;
255 final String actual = StringEscapeUtils.escapeJava(input);
256
257
258
259
260
261 assertEquals(expected, actual);
262 }
263
264 @Test
265 public void testEscapeJson() {
266 assertNull(StringEscapeUtils.escapeJson(null));
267 assertThrows(NullPointerException.class, () -> StringEscapeUtils.ESCAPE_JSON.translate(null, null));
268 assertThrows(NullPointerException.class, () -> StringEscapeUtils.ESCAPE_JSON.translate("", null));
269
270 assertEquals("He didn't say, \\\"stop!\\\"", StringEscapeUtils.escapeJson("He didn't say, \"stop!\""));
271
272 final String expected = "\\\"foo\\\" isn't \\\"bar\\\". specials: \\b\\r\\n\\f\\t\\\\\\/";
273 final String input ="\"foo\" isn't \"bar\". specials: \b\r\n\f\t\\/";
274
275 assertEquals(expected, StringEscapeUtils.escapeJson(input));
276 }
277
278 @Test
279 public void testEscapeXml() throws Exception {
280 assertEquals("<abc>", StringEscapeUtils.escapeXml("<abc>"));
281 assertEquals("<abc>", StringEscapeUtils.unescapeXml("<abc>"));
282
283 assertEquals("\u00A1", StringEscapeUtils.escapeXml("\u00A1"), "XML should not escape >0x7f values");
284 assertEquals("\u00A0", StringEscapeUtils.unescapeXml(" "), "XML should be able to unescape >0x7f values");
285 assertEquals("\u00A0", StringEscapeUtils.unescapeXml(" "),
286 "XML should be able to unescape >0x7f values with one leading 0");
287 assertEquals("\u00A0", StringEscapeUtils.unescapeXml(" "),
288 "XML should be able to unescape >0x7f values with two leading 0s");
289 assertEquals("\u00A0", StringEscapeUtils.unescapeXml(" "),
290 "XML should be able to unescape >0x7f values with three leading 0s");
291
292 assertEquals("ain't", StringEscapeUtils.unescapeXml("ain't"));
293 assertEquals("ain't", StringEscapeUtils.escapeXml("ain't"));
294 assertEquals("", StringEscapeUtils.escapeXml(""));
295 assertNull(StringEscapeUtils.escapeXml(null));
296 assertNull(StringEscapeUtils.unescapeXml(null));
297
298 StringWriter sw = new StringWriter();
299 StringEscapeUtils.ESCAPE_XML.translate("<abc>", sw);
300 assertEquals("<abc>", sw.toString(), "XML was escaped incorrectly");
301
302 sw = new StringWriter();
303 StringEscapeUtils.UNESCAPE_XML.translate("<abc>", sw);
304 assertEquals("<abc>", sw.toString(), "XML was unescaped incorrectly");
305 }
306
307 @Test
308 public void testEscapeXml10() {
309 assertEquals("a<b>c"d'e&f", StringEscapeUtils.escapeXml10("a<b>c\"d'e&f"));
310 assertEquals("a\tb\rc\nd", StringEscapeUtils.escapeXml10("a\tb\rc\nd"), "XML 1.0 should not escape \t \n \r");
311 assertEquals("ab", StringEscapeUtils.escapeXml10("a\u0000\u0001\u0008\u000b\u000c\u000e\u001fb"),
312 "XML 1.0 should omit most #x0-x8 | #xb | #xc | #xe-#x19");
313 assertEquals("a\ud7ff \ue000b", StringEscapeUtils.escapeXml10("a\ud7ff\ud800 \udfff \ue000b"),
314 "XML 1.0 should omit #xd800-#xdfff");
315 assertEquals("a\ufffdb", StringEscapeUtils.escapeXml10("a\ufffd\ufffe\uffffb"),
316 "XML 1.0 should omit #xfffe | #xffff");
317 assertEquals("a\u007e„\u0085†Ÿ\u00a0b",
318 StringEscapeUtils.escapeXml10("a\u007e\u007f\u0084\u0085\u0086\u009f\u00a0b"),
319 "XML 1.0 should escape #x7f-#x84 | #x86 - #x9f, for XML 1.1 compatibility");
320 }
321
322 @Test
323 public void testEscapeXml11() {
324 assertEquals("a<b>c"d'e&f", StringEscapeUtils.escapeXml11("a<b>c\"d'e&f"));
325 assertEquals("a\tb\rc\nd", StringEscapeUtils.escapeXml11("a\tb\rc\nd"), "XML 1.1 should not escape \t \n \r");
326 assertEquals("ab", StringEscapeUtils.escapeXml11("a\u0000b"), "XML 1.1 should omit #x0");
327 assertEquals("ab",
328 StringEscapeUtils.escapeXml11("a\u0001\u0008\u000b\u000c\u000e\u001fb"),
329 "XML 1.1 should escape #x1-x8 | #xb | #xc | #xe-#x19");
330 assertEquals("a\u007e„\u0085†Ÿ\u00a0b",
331 StringEscapeUtils.escapeXml11("a\u007e\u007f\u0084\u0085\u0086\u009f\u00a0b"),
332 "XML 1.1 should escape #x7F-#x84 | #x86-#x9F");
333 assertEquals("a\ud7ff \ue000b", StringEscapeUtils.escapeXml11("a\ud7ff\ud800 \udfff \ue000b"),
334 "XML 1.1 should omit #xd800-#xdfff");
335 assertEquals("a\ufffdb", StringEscapeUtils.escapeXml11("a\ufffd\ufffe\uffffb"),
336 "XML 1.1 should omit #xfffe | #xffff");
337 }
338
339 @Test
340 public void testEscapeXmlAllCharacters() {
341
342
343
344 final CharSequenceTranslator escapeXml = StringEscapeUtils.ESCAPE_XML
345 .with(NumericEntityEscaper.below(9), NumericEntityEscaper.between(0xB, 0xC), NumericEntityEscaper.between(0xE, 0x19),
346 NumericEntityEscaper.between(0xD800, 0xDFFF), NumericEntityEscaper.between(0xFFFE, 0xFFFF), NumericEntityEscaper.above(0x110000));
347
348 assertEquals("�", escapeXml.translate("\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\u0008"));
349 assertEquals("\t", escapeXml.translate("\t"));
350 assertEquals("\n", escapeXml.translate("\n"));
351 assertEquals("", escapeXml.translate("\u000B\u000C"));
352 assertEquals("\r", escapeXml.translate("\r"));
353 assertEquals("Hello World! Ain't this great?", escapeXml.translate("Hello World! Ain't this great?"));
354 assertEquals("", escapeXml.translate("\u000E\u000F\u0018\u0019"));
355 }
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372 @Test
373 public void testEscapeXmlSupplementaryCharacters() {
374 final CharSequenceTranslator escapeXml =
375 StringEscapeUtils.ESCAPE_XML.with( NumericEntityEscaper.between(0x7f, Integer.MAX_VALUE) );
376
377 assertEquals("𣎴", escapeXml.translate("\uD84C\uDFB4"),
378 "Supplementary character must be represented using a single escape");
379
380 assertEquals("a b c 𣎴", escapeXml.translate("a b c \uD84C\uDFB4"),
381 "Supplementary characters mixed with basic characters should be encoded correctly");
382 }
383
384 @Test
385 public void testLang313() {
386 assertEquals("& &", StringEscapeUtils.unescapeHtml4("& &"));
387 }
388
389
390
391
392
393
394
395 @Test
396 public void testLang708() throws IOException {
397 final byte[] inputBytes = Files.readAllBytes(Paths.get("src/test/resources/lang-708-input.txt"));
398 final String input = new String(inputBytes, StandardCharsets.UTF_8);
399 final String escaped = StringEscapeUtils.escapeEcmaScript(input);
400
401 assertTrue(escaped.endsWith("}]"), escaped);
402
403 assertTrue(escaped.endsWith("\"valueCode\\\":\\\"\\\"}]"), escaped);
404 }
405
406
407
408
409 @Test
410 public void testLang720() {
411 final String input = "\ud842\udfb7" + "A";
412 final String escaped = StringEscapeUtils.escapeXml(input);
413 assertEquals(input, escaped);
414 }
415
416
417
418
419 @Test
420 public void testLang911() {
421 final String bellsTest = "\ud83d\udc80\ud83d\udd14";
422 final String value = StringEscapeUtils.escapeJava(bellsTest);
423 final String valueTest = StringEscapeUtils.unescapeJava(value);
424 assertEquals(bellsTest, valueTest);
425 }
426
427
428
429 @Test
430 public void testStandaloneAmphersand() {
431 assertEquals("<P&O>", StringEscapeUtils.unescapeHtml4("<P&O>"));
432 assertEquals("test & <", StringEscapeUtils.unescapeHtml4("test & <"));
433 assertEquals("<P&O>", StringEscapeUtils.unescapeXml("<P&O>"));
434 assertEquals("test & <", StringEscapeUtils.unescapeXml("test & <"));
435 }
436
437 @Test
438 public void testUnescapeCsvIllegalStateException() {
439 final StringWriter writer = new StringWriter();
440 assertThrows(IllegalStateException.class, () -> StringEscapeUtils.UNESCAPE_CSV.translate("foo", -1, writer));
441 }
442
443 @Test
444 public void testUnescapeCsvString() {
445 assertEquals("foo.bar", StringEscapeUtils.unescapeCsv("foo.bar"));
446 assertEquals("foo,bar", StringEscapeUtils.unescapeCsv("\"foo,bar\""));
447 assertEquals("foo\nbar", StringEscapeUtils.unescapeCsv("\"foo\nbar\""));
448 assertEquals("foo\rbar", StringEscapeUtils.unescapeCsv("\"foo\rbar\""));
449 assertEquals("foo\"bar", StringEscapeUtils.unescapeCsv("\"foo\"\"bar\""));
450 assertEquals("foo\uD84C\uDFB4bar", StringEscapeUtils.unescapeCsv("foo\uD84C\uDFB4bar"));
451 assertEquals("", StringEscapeUtils.unescapeCsv(""));
452 assertNull(StringEscapeUtils.unescapeCsv(null));
453
454 assertEquals("\"foo.bar\"", StringEscapeUtils.unescapeCsv("\"foo.bar\""));
455 }
456
457 @Test
458 public void testUnescapeCsvWriter() throws Exception {
459 checkCsvUnescapeWriter("foo.bar", "foo.bar");
460 checkCsvUnescapeWriter("foo,bar", "\"foo,bar\"");
461 checkCsvUnescapeWriter("foo\nbar", "\"foo\nbar\"");
462 checkCsvUnescapeWriter("foo\rbar", "\"foo\rbar\"");
463 checkCsvUnescapeWriter("foo\"bar", "\"foo\"\"bar\"");
464 checkCsvUnescapeWriter("foo\uD84C\uDFB4bar", "foo\uD84C\uDFB4bar");
465 checkCsvUnescapeWriter("", null);
466 checkCsvUnescapeWriter("", "");
467
468 checkCsvUnescapeWriter("\"foo.bar\"", "\"foo.bar\"");
469 }
470
471 @Test
472 public void testUnescapeEcmaScript() {
473 assertNull(StringEscapeUtils.escapeEcmaScript(null));
474 assertThrows(NullPointerException.class, () -> StringEscapeUtils.UNESCAPE_ECMASCRIPT.translate(null, null));
475 assertThrows(NullPointerException.class, () -> StringEscapeUtils.UNESCAPE_ECMASCRIPT.translate("", null));
476
477 assertEquals("He didn't say, \"stop!\"", StringEscapeUtils.unescapeEcmaScript("He didn\\'t say, \\\"stop!\\\""));
478 assertEquals("document.getElementById(\"test\").value = '<script>alert('aaa');</script>';",
479 StringEscapeUtils.unescapeEcmaScript("document.getElementById(\\\"test\\\").value = \\'<script>alert(\\'aaa\\');<\\/script>\\';"));
480 }
481
482 @Test
483 public void testUnescapeHexCharsHtml() {
484
485 assertEquals("\u0080\u009F", StringEscapeUtils.unescapeHtml4("€Ÿ"), "hex number unescape");
486 assertEquals("\u0080\u009F", StringEscapeUtils.unescapeHtml4("€Ÿ"), "hex number unescape");
487
488 for (char i = Character.MIN_VALUE; i < Character.MAX_VALUE; i++) {
489 final Character c1 = Character.valueOf(i);
490 final Character c2 = Character.valueOf((char) (i+1));
491 final String expected = c1.toString() + c2.toString();
492 final String escapedC1 = "&#x" + Integer.toHexString((c1.charValue())) + ";";
493 final String escapedC2 = "&#x" + Integer.toHexString((c2.charValue())) + ";";
494 assertEquals(expected, StringEscapeUtils.unescapeHtml4(escapedC1 + escapedC2), "hex number unescape index " + (int) i);
495 }
496 }
497
498 @Test
499 public void testUnescapeHtml4() throws IOException {
500 for (final String[] element : HTML_ESCAPES) {
501 final String message = element[0];
502 final String expected = element[2];
503 final String original = element[1];
504 assertEquals(expected, StringEscapeUtils.unescapeHtml4(original), message);
505
506 final StringWriter sw = new StringWriter();
507 StringEscapeUtils.UNESCAPE_HTML4.translate(original, sw);
508 final String actual = original == null ? null : sw.toString();
509 assertEquals(expected, actual, message);
510 }
511
512
513
514 assertEquals("Fran\u00E7ais", StringEscapeUtils.unescapeHtml4("Fran\u00E7ais"), "funny chars pass through OK");
515
516 assertEquals("Hello&;World", StringEscapeUtils.unescapeHtml4("Hello&;World"));
517 assertEquals("Hello&#;World", StringEscapeUtils.unescapeHtml4("Hello&#;World"));
518 assertEquals("Hello&# ;World", StringEscapeUtils.unescapeHtml4("Hello&# ;World"));
519 assertEquals("Hello&##;World", StringEscapeUtils.unescapeHtml4("Hello&##;World"));
520 }
521
522 @Test
523 public void testUnescapeJava() throws IOException {
524 assertNull(StringEscapeUtils.unescapeJava(null));
525 assertThrows(NullPointerException.class, () -> StringEscapeUtils.UNESCAPE_JAVA.translate(null, null));
526 assertThrows(NullPointerException.class, () -> StringEscapeUtils.UNESCAPE_JAVA.translate("", null));
527 assertThrows(RuntimeException.class, () -> StringEscapeUtils.unescapeJava("\\u02-3"));
528
529 assertUnescapeJava("", "");
530 assertUnescapeJava("test", "test");
531 assertUnescapeJava("\ntest\b", "\\ntest\\b");
532 assertUnescapeJava("\u123425foo\ntest\b", "\\u123425foo\\ntest\\b");
533 assertUnescapeJava("'\foo\teste\r", "\\'\\foo\\teste\\r");
534 assertUnescapeJava("", "\\");
535
536 assertUnescapeJava("lowercase Unicode", "\uABCDx", "\\uabcdx");
537 assertUnescapeJava("uppercase Unicode", "\uABCDx", "\\uABCDx");
538 assertUnescapeJava("Unicode as final character", "\uABCD", "\\uabcd");
539 }
540
541 @Test
542 public void testUnescapeJson() {
543 assertNull(StringEscapeUtils.unescapeJson(null));
544 assertThrows(NullPointerException.class, () -> StringEscapeUtils.UNESCAPE_JSON.translate(null, null));
545 assertThrows(NullPointerException.class, () -> StringEscapeUtils.UNESCAPE_JSON.translate("", null));
546
547 assertEquals("He didn't say, \"stop!\"", StringEscapeUtils.unescapeJson("He didn't say, \\\"stop!\\\""));
548
549 final String expected ="\"foo\" isn't \"bar\". specials: \b\r\n\f\t\\/";
550 final String input = "\\\"foo\\\" isn't \\\"bar\\\". specials: \\b\\r\\n\\f\\t\\\\\\/";
551
552 assertEquals(expected, StringEscapeUtils.unescapeJson(input));
553 }
554
555 @Test
556 public void testUnescapeUnknownEntity() {
557 assertEquals("&zzzz;", StringEscapeUtils.unescapeHtml4("&zzzz;"));
558 }
559
560
561
562
563
564
565 @Test
566 public void testUnescapeXmlSupplementaryCharacters() {
567 assertEquals("\uD84C\uDFB4", StringEscapeUtils.unescapeXml("𣎴"),
568 "Supplementary character must be represented using a single escape");
569
570 assertEquals("a b c \uD84C\uDFB4", StringEscapeUtils.unescapeXml("a b c 𣎴"),
571 "Supplementary characters mixed with basic characters should be decoded correctly");
572 }
573 }