Escape current character output
ci/woodpecker/push/woodpecker Pipeline was successful
Details
ci/woodpecker/push/woodpecker Pipeline was successful
Details
This commit is contained in:
parent
ff4b1a7656
commit
57b2e54b5a
|
@ -22,6 +22,8 @@ import com.google.gson.Strictness;
|
|||
import com.google.gson.internal.DefaultConfig;
|
||||
import com.google.gson.internal.JsonReaderInternalAccess;
|
||||
import com.google.gson.internal.TroubleshootingGuide;
|
||||
import com.google.gson.util.StringEscapeUtil;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
|
@ -1611,7 +1613,11 @@ public class JsonReader implements Closeable {
|
|||
private String locationString() {
|
||||
int line = lineNumber + 1;
|
||||
int column = pos - lineStart + 1;
|
||||
String charInterjection = pos < buffer.length ? " (char '" + buffer[pos] + "')" : "";
|
||||
String replacement = StringEscapeUtil.getReplacement(buffer[pos]);
|
||||
if (replacement == null) {
|
||||
replacement = String.valueOf(buffer[pos]);
|
||||
}
|
||||
String charInterjection = pos < buffer.length ? " (char '" + replacement + "')" : "";
|
||||
return " at line " + line + " column " + column + charInterjection + " path " + getPath();
|
||||
}
|
||||
|
||||
|
|
|
@ -30,6 +30,8 @@ import com.google.gson.FormattingStyle;
|
|||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.Strictness;
|
||||
import com.google.gson.util.StringEscapeUtil;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.Flushable;
|
||||
import java.io.IOException;
|
||||
|
@ -166,39 +168,6 @@ public class JsonWriter implements Closeable, Flushable {
|
|||
private static final Pattern VALID_JSON_NUMBER_PATTERN =
|
||||
Pattern.compile("-?(?:0|[1-9][0-9]*)(?:\\.[0-9]+)?(?:[eE][-+]?[0-9]+)?");
|
||||
|
||||
/*
|
||||
* From RFC 8259, "All Unicode characters may be placed within the
|
||||
* quotation marks except for the characters that must be escaped:
|
||||
* quotation mark, reverse solidus, and the control characters
|
||||
* (U+0000 through U+001F)."
|
||||
*
|
||||
* We also escape '\u2028' and '\u2029', which JavaScript interprets as
|
||||
* newline characters. This prevents eval() from failing with a syntax
|
||||
* error. http://code.google.com/p/google-gson/issues/detail?id=341
|
||||
*/
|
||||
private static final String[] REPLACEMENT_CHARS;
|
||||
private static final String[] HTML_SAFE_REPLACEMENT_CHARS;
|
||||
|
||||
static {
|
||||
REPLACEMENT_CHARS = new String[128];
|
||||
for (int i = 0; i <= 0x1f; i++) {
|
||||
REPLACEMENT_CHARS[i] = String.format("\\u%04x", i);
|
||||
}
|
||||
REPLACEMENT_CHARS['"'] = "\\\"";
|
||||
REPLACEMENT_CHARS['\\'] = "\\\\";
|
||||
REPLACEMENT_CHARS['\t'] = "\\t";
|
||||
REPLACEMENT_CHARS['\b'] = "\\b";
|
||||
REPLACEMENT_CHARS['\n'] = "\\n";
|
||||
REPLACEMENT_CHARS['\r'] = "\\r";
|
||||
REPLACEMENT_CHARS['\f'] = "\\f";
|
||||
HTML_SAFE_REPLACEMENT_CHARS = REPLACEMENT_CHARS.clone();
|
||||
HTML_SAFE_REPLACEMENT_CHARS['<'] = "\\u003c";
|
||||
HTML_SAFE_REPLACEMENT_CHARS['>'] = "\\u003e";
|
||||
HTML_SAFE_REPLACEMENT_CHARS['&'] = "\\u0026";
|
||||
HTML_SAFE_REPLACEMENT_CHARS['='] = "\\u003d";
|
||||
HTML_SAFE_REPLACEMENT_CHARS['\''] = "\\u0027";
|
||||
}
|
||||
|
||||
/** The JSON output destination */
|
||||
private final Writer out;
|
||||
|
||||
|
@ -794,23 +763,13 @@ public class JsonWriter implements Closeable, Flushable {
|
|||
}
|
||||
|
||||
private void string(String value) throws IOException {
|
||||
String[] replacements = htmlSafe ? HTML_SAFE_REPLACEMENT_CHARS : REPLACEMENT_CHARS;
|
||||
out.write('\"');
|
||||
int last = 0;
|
||||
int length = value.length();
|
||||
for (int i = 0; i < length; i++) {
|
||||
char c = value.charAt(i);
|
||||
String replacement;
|
||||
if (c < 128) {
|
||||
replacement = replacements[c];
|
||||
if (replacement == null) {
|
||||
continue;
|
||||
}
|
||||
} else if (c == '\u2028') {
|
||||
replacement = "\\u2028";
|
||||
} else if (c == '\u2029') {
|
||||
replacement = "\\u2029";
|
||||
} else {
|
||||
String replacement = htmlSafe ? StringEscapeUtil.getHtmlSafeReplacement(c) : StringEscapeUtil.getReplacement(c);
|
||||
if (replacement == null) {
|
||||
continue;
|
||||
}
|
||||
if (last < i) {
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
package com.google.gson.util;
|
||||
|
||||
/**
|
||||
* Utilities methods for escaping strings, extracted from gsons JsonWriter.
|
||||
* @author JFronny
|
||||
*/
|
||||
public class StringEscapeUtil {
|
||||
private StringEscapeUtil() {}
|
||||
|
||||
/*
|
||||
* From RFC 8259, "All Unicode characters may be placed within the
|
||||
* quotation marks except for the characters that must be escaped:
|
||||
* quotation mark, reverse solidus, and the control characters
|
||||
* (U+0000 through U+001F)."
|
||||
*
|
||||
* We also escape '\u2028' and '\u2029', which JavaScript interprets as
|
||||
* newline characters. This prevents eval() from failing with a syntax
|
||||
* error. http://code.google.com/p/google-gson/issues/detail?id=341
|
||||
*/
|
||||
private static final String[] REPLACEMENT_CHARS;
|
||||
private static final String[] HTML_SAFE_REPLACEMENT_CHARS;
|
||||
|
||||
static {
|
||||
REPLACEMENT_CHARS = new String[128];
|
||||
for (int i = 0; i <= 0x1f; i++) {
|
||||
REPLACEMENT_CHARS[i] = String.format("\\u%04x", i);
|
||||
}
|
||||
REPLACEMENT_CHARS['"'] = "\\\"";
|
||||
REPLACEMENT_CHARS['\\'] = "\\\\";
|
||||
REPLACEMENT_CHARS['\t'] = "\\t";
|
||||
REPLACEMENT_CHARS['\b'] = "\\b";
|
||||
REPLACEMENT_CHARS['\n'] = "\\n";
|
||||
REPLACEMENT_CHARS['\r'] = "\\r";
|
||||
REPLACEMENT_CHARS['\f'] = "\\f";
|
||||
REPLACEMENT_CHARS['\0'] = "\\0";
|
||||
HTML_SAFE_REPLACEMENT_CHARS = REPLACEMENT_CHARS.clone();
|
||||
HTML_SAFE_REPLACEMENT_CHARS['<'] = "\\u003c";
|
||||
HTML_SAFE_REPLACEMENT_CHARS['>'] = "\\u003e";
|
||||
HTML_SAFE_REPLACEMENT_CHARS['&'] = "\\u0026";
|
||||
HTML_SAFE_REPLACEMENT_CHARS['='] = "\\u003d";
|
||||
HTML_SAFE_REPLACEMENT_CHARS['\''] = "\\u0027";
|
||||
}
|
||||
|
||||
private static String getReplacement(char c, String[] replacements) {
|
||||
String replacement;
|
||||
if (c < 128) {
|
||||
replacement = replacements[c];
|
||||
if (replacement == null) {
|
||||
return null;
|
||||
}
|
||||
} else if (c == '\u2028') {
|
||||
replacement = "\\u2028";
|
||||
} else if (c == '\u2029') {
|
||||
replacement = "\\u2029";
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
return replacement;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the replacement for the character, or null if the character does not need to be escaped.
|
||||
* @param c the character to escape
|
||||
* @return the replacement for the character, or null if the character does not need to be escaped
|
||||
* @see #getHtmlSafeReplacement(char)
|
||||
*/
|
||||
public static String getReplacement(char c) {
|
||||
return getReplacement(c, REPLACEMENT_CHARS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the replacement for the character, or null if the character does not need to be escaped.
|
||||
* @param c the character to escape
|
||||
* @return the replacement for the character, or null if the character does not need to be escaped
|
||||
* @see #getReplacement(char)
|
||||
*/
|
||||
public static String getHtmlSafeReplacement(char c) {
|
||||
return getReplacement(c, HTML_SAFE_REPLACEMENT_CHARS);
|
||||
}
|
||||
}
|
|
@ -40,7 +40,7 @@ public class ToNumberPolicyTest {
|
|||
assertThat(e)
|
||||
.hasMessageThat()
|
||||
.isEqualTo(
|
||||
"JSON forbids NaN and infinities: Infinity at line 1 column 6 (char '\0') path $\n"
|
||||
"JSON forbids NaN and infinities: Infinity at line 1 column 6 (char '\\0') path $\n"
|
||||
+ "See https://github.com/google/gson/blob/main/Troubleshooting.md#malformed-json");
|
||||
|
||||
assertThrows(
|
||||
|
@ -133,7 +133,7 @@ public class ToNumberPolicyTest {
|
|||
assertThat(e)
|
||||
.hasMessageThat()
|
||||
.isEqualTo(
|
||||
"Expected a double but was NULL at line 1 column 5 (char '\0') path $\n"
|
||||
"Expected a double but was NULL at line 1 column 5 (char '\\0') path $\n"
|
||||
+ "See https://github.com/google/gson/blob/main/Troubleshooting.md#adapter-not-null-safe");
|
||||
|
||||
e =
|
||||
|
@ -143,7 +143,7 @@ public class ToNumberPolicyTest {
|
|||
assertThat(e)
|
||||
.hasMessageThat()
|
||||
.isEqualTo(
|
||||
"Expected a string but was NULL at line 1 column 5 (char '\0') path $\n"
|
||||
"Expected a string but was NULL at line 1 column 5 (char '\\0') path $\n"
|
||||
+ "See https://github.com/google/gson/blob/main/Troubleshooting.md#adapter-not-null-safe");
|
||||
|
||||
e =
|
||||
|
@ -153,7 +153,7 @@ public class ToNumberPolicyTest {
|
|||
assertThat(e)
|
||||
.hasMessageThat()
|
||||
.isEqualTo(
|
||||
"Expected a string but was NULL at line 1 column 5 (char '\0') path $\n"
|
||||
"Expected a string but was NULL at line 1 column 5 (char '\\0') path $\n"
|
||||
+ "See https://github.com/google/gson/blob/main/Troubleshooting.md#adapter-not-null-safe");
|
||||
|
||||
e =
|
||||
|
@ -163,7 +163,7 @@ public class ToNumberPolicyTest {
|
|||
assertThat(e)
|
||||
.hasMessageThat()
|
||||
.isEqualTo(
|
||||
"Expected a string but was NULL at line 1 column 5 (char '\0') path $\n"
|
||||
"Expected a string but was NULL at line 1 column 5 (char '\\0') path $\n"
|
||||
+ "See https://github.com/google/gson/blob/main/Troubleshooting.md#adapter-not-null-safe");
|
||||
}
|
||||
|
||||
|
|
|
@ -97,7 +97,7 @@ public class PrimitiveTest {
|
|||
.hasMessageThat()
|
||||
.isEqualTo(
|
||||
"java.lang.NumberFormatException: Expected an int but was 2147483648"
|
||||
+ " at line 1 column 11 (char '\0') path $");
|
||||
+ " at line 1 column 11 (char '\\0') path $");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -140,7 +140,7 @@ public class PrimitiveTest {
|
|||
.hasMessageThat()
|
||||
.isEqualTo(
|
||||
"java.lang.NumberFormatException: Expected an int but was 2147483648"
|
||||
+ " at line 1 column 11 (char '\0') path $");
|
||||
+ " at line 1 column 11 (char '\\0') path $");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -915,7 +915,7 @@ public class PrimitiveTest {
|
|||
assertThat(e)
|
||||
.hasCauseThat()
|
||||
.hasMessageThat()
|
||||
.isEqualTo("Expected an int but was -122.08e-213 at line 1 column 13 (char '\0') path $");
|
||||
.isEqualTo("Expected an int but was -122.08e-213 at line 1 column 13 (char '\\0') path $");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -926,7 +926,7 @@ public class PrimitiveTest {
|
|||
assertThat(e)
|
||||
.hasCauseThat()
|
||||
.hasMessageThat()
|
||||
.isEqualTo("Expected an int but was " + number + " at line 1 column 57 (char '\0') path $");
|
||||
.isEqualTo("Expected an int but was " + number + " at line 1 column 57 (char '\\0') path $");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -937,7 +937,7 @@ public class PrimitiveTest {
|
|||
assertThat(e)
|
||||
.hasCauseThat()
|
||||
.hasMessageThat()
|
||||
.isEqualTo("Expected a long but was " + number + " at line 1 column 57 (char '\0') path $");
|
||||
.isEqualTo("Expected a long but was " + number + " at line 1 column 57 (char '\\0') path $");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -1175,27 +1175,27 @@ public final class JsonReaderTest {
|
|||
fail();
|
||||
} catch (IllegalStateException expected) {
|
||||
assertUnexpectedStructureError(
|
||||
expected, "a string", "END_OBJECT", "line 1 column 11 (char '\0') path $.a");
|
||||
expected, "a string", "END_OBJECT", "line 1 column 11 (char '\\0') path $.a");
|
||||
}
|
||||
try {
|
||||
reader.nextName();
|
||||
fail();
|
||||
} catch (IllegalStateException expected) {
|
||||
assertUnexpectedStructureError(expected, "a name", "END_OBJECT", "line 1 column 11 (char '\0') path $.a");
|
||||
assertUnexpectedStructureError(expected, "a name", "END_OBJECT", "line 1 column 11 (char '\\0') path $.a");
|
||||
}
|
||||
try {
|
||||
reader.beginArray();
|
||||
fail();
|
||||
} catch (IllegalStateException expected) {
|
||||
assertUnexpectedStructureError(
|
||||
expected, "BEGIN_ARRAY", "END_OBJECT", "line 1 column 11 (char '\0') path $.a");
|
||||
expected, "BEGIN_ARRAY", "END_OBJECT", "line 1 column 11 (char '\\0') path $.a");
|
||||
}
|
||||
try {
|
||||
reader.endArray();
|
||||
fail();
|
||||
} catch (IllegalStateException expected) {
|
||||
assertUnexpectedStructureError(
|
||||
expected, "END_ARRAY", "END_OBJECT", "line 1 column 11 (char '\0') path $.a");
|
||||
expected, "END_ARRAY", "END_OBJECT", "line 1 column 11 (char '\\0') path $.a");
|
||||
}
|
||||
reader.endObject();
|
||||
assertThat(reader.peek()).isEqualTo(JsonToken.END_DOCUMENT);
|
||||
|
@ -1623,7 +1623,7 @@ public final class JsonReaderTest {
|
|||
reader.nextNull();
|
||||
fail();
|
||||
} catch (IllegalStateException expected) {
|
||||
assertThat(expected).hasMessageThat().startsWith("Expected null but was END_ARRAY at line 1 column 8 (char '\0') path $[1]");
|
||||
assertThat(expected).hasMessageThat().startsWith("Expected null but was END_ARRAY at line 1 column 8 (char '\\0') path $[1]");
|
||||
}
|
||||
|
||||
reader = new JsonReader(reader("[,]"));
|
||||
|
@ -2109,7 +2109,7 @@ public final class JsonReaderTest {
|
|||
assertThat(expected)
|
||||
.hasMessageThat()
|
||||
.isEqualTo(
|
||||
"Unterminated object at x at line 1 column 16 (char '\0') path $.a\n"
|
||||
"Unterminated object at x at line 1 column 16 (char '\\0') path $.a\n"
|
||||
+ "See https://github.com/google/gson/blob/main/Troubleshooting.md#malformed-json");
|
||||
}
|
||||
}
|
||||
|
@ -2241,7 +2241,7 @@ public final class JsonReaderTest {
|
|||
assertThat(expected)
|
||||
.hasMessageThat()
|
||||
.isEqualTo(
|
||||
"Expected name at line 1 column 11 (char '\0') path $.a\n"
|
||||
"Expected name at line 1 column 11 (char '\\0') path $.a\n"
|
||||
+ "See https://github.com/google/gson/blob/main/Troubleshooting.md#malformed-json");
|
||||
}
|
||||
}
|
||||
|
@ -2260,7 +2260,7 @@ public final class JsonReaderTest {
|
|||
assertThat(expected)
|
||||
.hasMessageThat()
|
||||
.isEqualTo(
|
||||
"Expected name at line 1 column 11 (char '\0') path $.a\n"
|
||||
"Expected name at line 1 column 11 (char '\\0') path $.a\n"
|
||||
+ "See https://github.com/google/gson/blob/main/Troubleshooting.md#malformed-json");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -698,7 +698,7 @@ public final class JsonWriterTest {
|
|||
+ "\"}\","
|
||||
+ "\"[\","
|
||||
+ "\"]\","
|
||||
+ "\"\\u0000\","
|
||||
+ "\"\\0\","
|
||||
+ "\"\\u0019\"]");
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue