Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support strict mode for JsonParser #2648

Merged
merged 2 commits into from
Mar 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 6 additions & 3 deletions gson/src/main/java/com/google/gson/Gson.java
Expand Up @@ -930,7 +930,8 @@ public void toJson(Object src, Type typeOfSrc, JsonWriter writer) throws JsonIOE
Strictness oldStrictness = writer.getStrictness();
if (this.strictness != null) {
writer.setStrictness(this.strictness);
} else if (writer.getStrictness() != Strictness.STRICT) {
} else if (writer.getStrictness() == Strictness.LEGACY_STRICT) {
// For backward compatibility change to LENIENT if writer has default strictness LEGACY_STRICT
writer.setStrictness(Strictness.LENIENT);
}

Expand Down Expand Up @@ -1013,7 +1014,8 @@ public void toJson(JsonElement jsonElement, JsonWriter writer) throws JsonIOExce

if (this.strictness != null) {
writer.setStrictness(this.strictness);
} else if (writer.getStrictness() != Strictness.STRICT) {
} else if (writer.getStrictness() == Strictness.LEGACY_STRICT) {
// For backward compatibility change to LENIENT if writer has default strictness LEGACY_STRICT
writer.setStrictness(Strictness.LENIENT);
}

Expand Down Expand Up @@ -1347,7 +1349,8 @@ public <T> T fromJson(JsonReader reader, TypeToken<T> typeOfT)

if (this.strictness != null) {
reader.setStrictness(this.strictness);
} else if (reader.getStrictness() != Strictness.STRICT) {
} else if (reader.getStrictness() == Strictness.LEGACY_STRICT) {
// For backward compatibility change to LENIENT if reader has default strictness LEGACY_STRICT
reader.setStrictness(Strictness.LENIENT);
}

Expand Down
12 changes: 8 additions & 4 deletions gson/src/main/java/com/google/gson/JsonParser.java
Expand Up @@ -87,9 +87,10 @@ public static JsonElement parseReader(Reader reader) throws JsonIOException, Jso
* methods, no exception is thrown if the JSON data has multiple top-level JSON elements, or if
* there is trailing data.
*
* <p>The JSON data is parsed in {@linkplain JsonReader#setStrictness(Strictness) lenient mode},
* regardless of the strictness setting of the provided reader. The strictness setting of the
* reader is restored once this method returns.
* <p>If the {@linkplain JsonReader#getStrictness() strictness of the reader} is {@link
* Strictness#STRICT}, that strictness will be used for parsing. Otherwise the strictness will be
* temporarily changed to {@link Strictness#LENIENT} and will be restored once this method
* returns.
*
* @throws JsonParseException if there is an IOException or if the specified text is not valid
* JSON
Expand All @@ -98,7 +99,10 @@ public static JsonElement parseReader(Reader reader) throws JsonIOException, Jso
public static JsonElement parseReader(JsonReader reader)
throws JsonIOException, JsonSyntaxException {
Strictness strictness = reader.getStrictness();
reader.setStrictness(Strictness.LENIENT);
if (strictness == Strictness.LEGACY_STRICT) {
// For backward compatibility change to LENIENT if reader has default strictness LEGACY_STRICT
reader.setStrictness(Strictness.LENIENT);
}
try {
return Streams.parse(reader);
} catch (StackOverflowError e) {
Expand Down
3 changes: 2 additions & 1 deletion gson/src/main/java/com/google/gson/stream/JsonReader.java
Expand Up @@ -336,7 +336,7 @@ public final void setLenient(boolean lenient) {
/**
* Returns true if the {@link Strictness} of this reader is equal to {@link Strictness#LENIENT}.
*
* @see #setStrictness(Strictness)
* @see #getStrictness()
*/
public final boolean isLenient() {
return strictness == Strictness.LENIENT;
Expand Down Expand Up @@ -393,6 +393,7 @@ public final boolean isLenient() {
* </dl>
*
* @param strictness the new strictness value of this reader. May not be {@code null}.
* @see #getStrictness()
* @since $next-version$
*/
public final void setStrictness(Strictness strictness) {
Expand Down
3 changes: 2 additions & 1 deletion gson/src/main/java/com/google/gson/stream/JsonWriter.java
Expand Up @@ -316,7 +316,7 @@ public final void setLenient(boolean lenient) {
/**
* Returns true if the {@link Strictness} of this writer is equal to {@link Strictness#LENIENT}.
*
* @see JsonWriter#setStrictness(Strictness)
* @see #getStrictness()
*/
public boolean isLenient() {
return strictness == Strictness.LENIENT;
Expand All @@ -338,6 +338,7 @@ public boolean isLenient() {
* </dl>
*
* @param strictness the new strictness of this writer. May not be {@code null}.
* @see #getStrictness()
* @since $next-version$
*/
public final void setStrictness(Strictness strictness) {
Expand Down
21 changes: 18 additions & 3 deletions gson/src/test/java/com/google/gson/JsonParserTest.java
Expand Up @@ -173,15 +173,30 @@ public void testReadWriteTwoObjects() throws Exception {
assertThat(actualTwo.stringValue).isEqualTo("two");
}

@Test
public void testLegacyStrict() {
JsonReader reader = new JsonReader(new StringReader("unquoted"));
Strictness strictness = Strictness.LEGACY_STRICT;
// LEGACY_STRICT is ignored by JsonParser later; parses in lenient mode instead
reader.setStrictness(strictness);

assertThat(JsonParser.parseReader(reader)).isEqualTo(new JsonPrimitive("unquoted"));
// Original strictness was restored
assertThat(reader.getStrictness()).isEqualTo(strictness);
}

@Test
public void testStrict() {
JsonReader reader = new JsonReader(new StringReader("faLsE"));
Strictness strictness = Strictness.STRICT;
// Strictness is ignored by JsonParser later; always parses in lenient mode
reader.setStrictness(strictness);

assertThat(JsonParser.parseReader(reader)).isEqualTo(new JsonPrimitive(false));
// Original strictness was restored
var e = assertThrows(JsonSyntaxException.class, () -> JsonParser.parseReader(reader));
assertThat(e)
.hasCauseThat()
.hasMessageThat()
.startsWith("Use JsonReader.setStrictness(Strictness.LENIENT) to accept malformed JSON");
// Original strictness was kept
assertThat(reader.getStrictness()).isEqualTo(strictness);
}
}
6 changes: 6 additions & 0 deletions gson/src/test/java/com/google/gson/stream/JsonReaderTest.java
Expand Up @@ -41,6 +41,12 @@
@SuppressWarnings("resource")
public final class JsonReaderTest {

@Test
public void testDefaultStrictness() {
JsonReader reader = new JsonReader(reader("{}"));
assertThat(reader.getStrictness()).isEqualTo(Strictness.LEGACY_STRICT);
}

@SuppressWarnings("deprecation") // for JsonReader.setLenient
@Test
public void testSetLenientTrue() {
Expand Down