|
23 | 23 | import org.elasticsearch.common.util.concurrent.ThreadContext;
|
24 | 24 | import org.elasticsearch.test.ESTestCase;
|
25 | 25 | import org.elasticsearch.test.hamcrest.RegexMatcher;
|
| 26 | +import org.hamcrest.core.IsSame; |
26 | 27 |
|
27 | 28 | import java.io.IOException;
|
28 | 29 | import java.util.Collections;
|
29 | 30 | import java.util.HashSet;
|
30 | 31 | import java.util.List;
|
| 32 | +import java.util.Locale; |
31 | 33 | import java.util.Map;
|
32 | 34 | import java.util.Set;
|
33 | 35 | import java.util.stream.IntStream;
|
@@ -71,6 +73,54 @@ public void testAddsHeaderWithThreadContext() throws IOException {
|
71 | 73 | }
|
72 | 74 | }
|
73 | 75 |
|
| 76 | + public void testContainingNewline() throws IOException { |
| 77 | + try (ThreadContext threadContext = new ThreadContext(Settings.EMPTY)) { |
| 78 | + final Set<ThreadContext> threadContexts = Collections.singleton(threadContext); |
| 79 | + |
| 80 | + logger.deprecated(threadContexts, "this message contains a newline\n"); |
| 81 | + |
| 82 | + final Map<String, List<String>> responseHeaders = threadContext.getResponseHeaders(); |
| 83 | + |
| 84 | + assertThat(responseHeaders.size(), equalTo(1)); |
| 85 | + final List<String> responses = responseHeaders.get("Warning"); |
| 86 | + assertThat(responses, hasSize(1)); |
| 87 | + assertThat(responses.get(0), warningValueMatcher); |
| 88 | + assertThat(responses.get(0), containsString("\"this message contains a newline%0A\"")); |
| 89 | + } |
| 90 | + } |
| 91 | + |
| 92 | + public void testSurrogatePair() throws IOException { |
| 93 | + try (ThreadContext threadContext = new ThreadContext(Settings.EMPTY)) { |
| 94 | + final Set<ThreadContext> threadContexts = Collections.singleton(threadContext); |
| 95 | + |
| 96 | + logger.deprecated(threadContexts, "this message contains a surrogate pair 😱"); |
| 97 | + |
| 98 | + final Map<String, List<String>> responseHeaders = threadContext.getResponseHeaders(); |
| 99 | + |
| 100 | + assertThat(responseHeaders.size(), equalTo(1)); |
| 101 | + final List<String> responses = responseHeaders.get("Warning"); |
| 102 | + assertThat(responses, hasSize(1)); |
| 103 | + assertThat(responses.get(0), warningValueMatcher); |
| 104 | + |
| 105 | + // convert UTF-16 to UTF-8 by hand to show the hard-coded constant below is correct |
| 106 | + assertThat("😱", equalTo("\uD83D\uDE31")); |
| 107 | + final int code = 0x10000 + ((0xD83D & 0x3FF) << 10) + (0xDE31 & 0x3FF); |
| 108 | + @SuppressWarnings("PointlessBitwiseExpression") |
| 109 | + final int[] points = new int[] { |
| 110 | + (code >> 18) & 0x07 | 0xF0, |
| 111 | + (code >> 12) & 0x3F | 0x80, |
| 112 | + (code >> 6) & 0x3F | 0x80, |
| 113 | + (code >> 0) & 0x3F | 0x80}; |
| 114 | + final StringBuilder sb = new StringBuilder(); |
| 115 | + // noinspection ForLoopReplaceableByForEach |
| 116 | + for (int i = 0; i < points.length; i++) { |
| 117 | + sb.append("%").append(Integer.toString(points[i], 16).toUpperCase(Locale.ROOT)); |
| 118 | + } |
| 119 | + assertThat(sb.toString(), equalTo("%F0%9F%98%B1")); |
| 120 | + assertThat(responses.get(0), containsString("\"this message contains a surrogate pair %F0%9F%98%B1\"")); |
| 121 | + } |
| 122 | + } |
| 123 | + |
74 | 124 | public void testAddsCombinedHeaderWithThreadContext() throws IOException {
|
75 | 125 | try (ThreadContext threadContext = new ThreadContext(Settings.EMPTY)) {
|
76 | 126 | final Set<ThreadContext> threadContexts = Collections.singleton(threadContext);
|
@@ -172,15 +222,28 @@ public void testWarningValueFromWarningHeader() throws InterruptedException {
|
172 | 222 | assertThat(DeprecationLogger.extractWarningValueFromWarningHeader(first), equalTo(s));
|
173 | 223 | }
|
174 | 224 |
|
175 |
| - public void testEscape() { |
176 |
| - assertThat(DeprecationLogger.escape("\\"), equalTo("\\\\")); |
177 |
| - assertThat(DeprecationLogger.escape("\""), equalTo("\\\"")); |
178 |
| - assertThat(DeprecationLogger.escape("\\\""), equalTo("\\\\\\\"")); |
179 |
| - assertThat(DeprecationLogger.escape("\"foo\\bar\""),equalTo("\\\"foo\\\\bar\\\"")); |
| 225 | + public void testEscapeBackslashesAndQuotes() { |
| 226 | + assertThat(DeprecationLogger.escapeBackslashesAndQuotes("\\"), equalTo("\\\\")); |
| 227 | + assertThat(DeprecationLogger.escapeBackslashesAndQuotes("\""), equalTo("\\\"")); |
| 228 | + assertThat(DeprecationLogger.escapeBackslashesAndQuotes("\\\""), equalTo("\\\\\\\"")); |
| 229 | + assertThat(DeprecationLogger.escapeBackslashesAndQuotes("\"foo\\bar\""),equalTo("\\\"foo\\\\bar\\\"")); |
180 | 230 | // test that characters other than '\' and '"' are left unchanged
|
181 |
| - String chars = "\t !" + range(0x23, 0x5b) + range(0x5d, 0x73) + range(0x80, 0xff); |
| 231 | + String chars = "\t !" + range(0x23, 0x24) + range(0x26, 0x5b) + range(0x5d, 0x73) + range(0x80, 0xff); |
| 232 | + final String s = new CodepointSetGenerator(chars.toCharArray()).ofCodePointsLength(random(), 16, 16); |
| 233 | + assertThat(DeprecationLogger.escapeBackslashesAndQuotes(s), equalTo(s)); |
| 234 | + } |
| 235 | + |
| 236 | + public void testEncode() { |
| 237 | + assertThat(DeprecationLogger.encode("\n"), equalTo("%0A")); |
| 238 | + assertThat(DeprecationLogger.encode("😱"), equalTo("%F0%9F%98%B1")); |
| 239 | + assertThat(DeprecationLogger.encode("福島深雪"), equalTo("%E7%A6%8F%E5%B3%B6%E6%B7%B1%E9%9B%AA")); |
| 240 | + assertThat(DeprecationLogger.encode("100%\n"), equalTo("100%25%0A")); |
| 241 | + // test that valid characters are left unchanged |
| 242 | + String chars = "\t !" + range(0x23, 0x24) + range(0x26, 0x5b) + range(0x5d, 0x73) + range(0x80, 0xff) + '\\' + '"'; |
182 | 243 | final String s = new CodepointSetGenerator(chars.toCharArray()).ofCodePointsLength(random(), 16, 16);
|
183 |
| - assertThat(DeprecationLogger.escape(s), equalTo(s)); |
| 244 | + assertThat(DeprecationLogger.encode(s), equalTo(s)); |
| 245 | + // when no encoding is needed, the original string is returned (optimization) |
| 246 | + assertThat(DeprecationLogger.encode(s), IsSame.sameInstance(s)); |
184 | 247 | }
|
185 | 248 |
|
186 | 249 | private String range(int lowerInclusive, int upperInclusive) {
|
|
0 commit comments