|
16 | 16 | */ |
17 | 17 | package org.apache.logging.log4j.util; |
18 | 18 |
|
| 19 | +import static org.assertj.core.api.Assertions.assertThat; |
19 | 20 | import static org.junit.jupiter.api.Assertions.assertEquals; |
20 | 21 | import static org.junit.jupiter.api.Assertions.assertTrue; |
21 | 22 |
|
| 23 | +import java.util.stream.Stream; |
22 | 24 | import org.junit.jupiter.api.Test; |
| 25 | +import org.junit.jupiter.params.ParameterizedTest; |
| 26 | +import org.junit.jupiter.params.provider.Arguments; |
| 27 | +import org.junit.jupiter.params.provider.MethodSource; |
23 | 28 |
|
24 | 29 | /** |
25 | 30 | * Tests the StringBuilders class. |
@@ -79,15 +84,37 @@ void escapeJsonCharactersISOControl() { |
79 | 84 | assertEquals(jsonValueEscaped, sb.toString()); |
80 | 85 | } |
81 | 86 |
|
82 | | - @Test |
83 | | - void escapeXMLCharactersCorrectly() { |
84 | | - final String xmlValueNotEscaped = "<\"Salt&Peppa'\">"; |
85 | | - final String xmlValueEscaped = "<"Salt&Peppa'">"; |
| 87 | + static Stream<Arguments> escapeXmlCharactersCorrectly() { |
| 88 | + final char replacement = '\uFFFD'; |
| 89 | + return Stream.of( |
| 90 | + // Empty |
| 91 | + Arguments.of("", ""), |
| 92 | + // characters that need to be escaped |
| 93 | + Arguments.of("<\"Salt&Peppa'\">", "<"Salt&Peppa'">"), |
| 94 | + // control character replaced with U+FFFD |
| 95 | + Arguments.of("A" + (char) 0x01 + "B", "A" + replacement + "B"), |
| 96 | + // standalone low surrogate replaced with U+FFFD |
| 97 | + Arguments.of("low" + Character.MIN_LOW_SURROGATE + "surrogate", "low" + replacement + "surrogate"), |
| 98 | + Arguments.of(Character.MIN_LOW_SURROGATE + "low", replacement + "low"), |
| 99 | + // standalone high surrogate replaced with U+FFFD |
| 100 | + Arguments.of("high" + Character.MIN_HIGH_SURROGATE + "surrogate", "high" + replacement + "surrogate"), |
| 101 | + Arguments.of(Character.MIN_HIGH_SURROGATE + "high", replacement + "high"), |
| 102 | + // FFFE and FFFF |
| 103 | + Arguments.of("invalid\uFFFEchars", "invalid" + replacement + "chars"), |
| 104 | + Arguments.of("invalid\uFFFFchars", "invalid" + replacement + "chars"), |
| 105 | + // whitespace characters are preserved |
| 106 | + Arguments.of("tab\tnewline\ncr\r", "tab\tnewline\ncr\r"), |
| 107 | + // character beyond BMP (emoji) preserved as surrogate pair |
| 108 | + Arguments.of("emoji " + "\uD83D\uDE00" + " end", "emoji " + "\uD83D\uDE00" + " end")); |
| 109 | + } |
86 | 110 |
|
| 111 | + @ParameterizedTest |
| 112 | + @MethodSource |
| 113 | + void escapeXmlCharactersCorrectly(final String input, final String expected) { |
87 | 114 | final StringBuilder sb = new StringBuilder(); |
88 | | - sb.append(xmlValueNotEscaped); |
89 | | - assertEquals(xmlValueNotEscaped, sb.toString()); |
| 115 | + sb.append(input); |
| 116 | + assertThat(sb.toString()).isEqualTo(input); |
90 | 117 | StringBuilders.escapeXml(sb, 0); |
91 | | - assertEquals(xmlValueEscaped, sb.toString()); |
| 118 | + assertThat(sb.toString()).isEqualTo(expected); |
92 | 119 | } |
93 | 120 | } |
0 commit comments