Skip to content

Commit 1693436

Browse files
committed
Gson respects the lenient flag
1 parent 2271525 commit 1693436

File tree

4 files changed

+85
-15
lines changed

4 files changed

+85
-15
lines changed

gson/src/main/java/com/google/gson/Gson.java

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@
102102
*/
103103
public final class Gson {
104104
static final boolean DEFAULT_JSON_NON_EXECUTABLE = false;
105-
static final boolean DEFAULT_LENIENT = false;
105+
static final boolean DEFAULT_LENIENT = true;
106106
static final boolean DEFAULT_PRETTY_PRINT = false;
107107
static final boolean DEFAULT_ESCAPE_HTML = true;
108108
static final boolean DEFAULT_SERIALIZE_NULLS = false;
@@ -870,15 +870,15 @@ private static void assertFullConsumption(Object obj, JsonReader reader) {
870870
* Reads the next JSON value from {@code reader} and convert it to an object
871871
* of type {@code typeOfT}. Returns {@code null}, if the {@code reader} is at EOF.
872872
* Since Type is not parameterized by T, this method is type unsafe and should be used carefully
873-
*
873+
* <p>
874+
* The leniency of the reader passed in is respected. See {@linkplain JsonReader#setLenient(boolean)}
875+
* </p>
874876
* @throws JsonIOException if there was a problem writing to the Reader
875877
* @throws JsonSyntaxException if json is not a valid representation for an object of type
876878
*/
877879
@SuppressWarnings("unchecked")
878880
public <T> T fromJson(JsonReader reader, Type typeOfT) throws JsonIOException, JsonSyntaxException {
879881
boolean isEmpty = true;
880-
boolean oldLenient = reader.isLenient();
881-
reader.setLenient(true);
882882
try {
883883
reader.peek();
884884
isEmpty = false;
@@ -900,8 +900,6 @@ public <T> T fromJson(JsonReader reader, Type typeOfT) throws JsonIOException, J
900900
} catch (IOException e) {
901901
// TODO(inder): Figure out whether it is indeed right to rethrow this as JsonSyntaxException
902902
throw new JsonSyntaxException(e);
903-
} finally {
904-
reader.setLenient(oldLenient);
905903
}
906904
}
907905

gson/src/main/java/com/google/gson/GsonBuilder.java

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -363,13 +363,23 @@ public GsonBuilder setPrettyPrinting() {
363363
}
364364

365365
/**
366-
* By default, Gson is strict and only accepts JSON as specified by
367-
* <a href="http://www.ietf.org/rfc/rfc4627.txt">RFC 4627</a>. This option makes the parser
368-
* liberal in what it accepts.
366+
* By default, Gson is liberal in what it accepts. Setting lenient to false causes Gson to
367+
* only accept JSON as specified by
368+
* <a href="http://www.ietf.org/rfc/rfc4627.txt">RFC 4627</a>.
369369
*
370370
* @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
371371
* @see JsonReader#setLenient(boolean)
372372
*/
373+
public GsonBuilder setLenient(boolean lenient) {
374+
this.lenient = lenient;
375+
return this;
376+
}
377+
378+
/**
379+
* Gson is lenient by default. Use {@link #setLenient(boolean)} if
380+
* you wish to change the leniency
381+
* @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
382+
*/
373383
public GsonBuilder setLenient() {
374384
lenient = true;
375385
return this;

gson/src/test/java/com/google/gson/functional/LeniencyTest.java

Lines changed: 66 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,30 +17,91 @@
1717

1818
import com.google.gson.Gson;
1919
import com.google.gson.GsonBuilder;
20+
import com.google.gson.JsonSyntaxException;
2021
import com.google.gson.reflect.TypeToken;
22+
import com.google.gson.stream.JsonReader;
23+
2124
import java.util.List;
2225
import junit.framework.TestCase;
2326

2427
import static java.util.Collections.singletonList;
2528

29+
import java.io.StringReader;
30+
import java.lang.reflect.Type;
31+
2632
/**
2733
* Functional tests for leniency option.
2834
*/
2935
public class LeniencyTest extends TestCase {
3036

31-
private Gson gson;
37+
private Gson lenientGson;
38+
private Gson strictGson;
3239

3340
@Override
3441
protected void setUp() throws Exception {
3542
super.setUp();
36-
gson = new GsonBuilder().setLenient().create();
43+
lenientGson = new GsonBuilder().create();
44+
strictGson = new GsonBuilder().setLenient(false).create();
3745
}
3846

3947
public void testLenientFromJson() {
40-
List<String> json = gson.fromJson(""
48+
final String testString = ""
49+
+ "[ # One!\n"
50+
+ " 'Hi' #Element!\n"
51+
+ "] # Array!";
52+
final String expectedResult = "Hi";
53+
Type type = new TypeToken<List<String>>() {}.getType();
54+
55+
JsonReader reader = new JsonReader(new StringReader(testString));
56+
reader.setLenient(true);
57+
// fromJson(JsonReader, Type) should respect the leniency of
58+
// the JsonReader
59+
List<String> json = strictGson.fromJson(reader, type);
60+
assertEquals(singletonList(expectedResult), json);
61+
62+
// the factory method should set the leniency of the created factory
63+
// to be the same as the leniency of the Gson instance
64+
reader = lenientGson.newJsonReader(new StringReader(testString));
65+
assertTrue(reader.isLenient());
66+
// fromJson(JsonReader, Type) should respect the leniency of
67+
// the JsonReader
68+
json = strictGson.fromJson(reader, type);
69+
assertEquals(singletonList(expectedResult), json);
70+
71+
json = lenientGson.fromJson(testString, type);
72+
assertEquals(singletonList(expectedResult), json);
73+
}
74+
75+
public void testStrictFromJson() {
76+
final String testString = ""
4177
+ "[ # One!\n"
4278
+ " 'Hi' #Element!\n"
43-
+ "] # Array!", new TypeToken<List<String>>() {}.getType());
44-
assertEquals(singletonList("Hi"), json);
79+
+ "]";
80+
Type type = new TypeToken<List<String>>(){}.getType();
81+
82+
try {
83+
// JsonReader is strict by default
84+
JsonReader reader = new JsonReader(new StringReader(testString));
85+
// fromJson(JsonReader, Type) should respect the leniency of
86+
// the JsonReader
87+
lenientGson.fromJson(reader, type);
88+
fail();
89+
} catch (JsonSyntaxException expected) { }
90+
91+
try {
92+
// the factory method should set the leniency of the created factory
93+
// to be the same as the leniency of the Gson instance
94+
JsonReader reader = strictGson.newJsonReader(new StringReader(testString));
95+
assertFalse(reader.isLenient());
96+
// fromJson(JsonReader, Type) should respect the leniency of
97+
// the JsonReader
98+
lenientGson.fromJson(reader, type);
99+
fail();
100+
} catch(JsonSyntaxException expected) { }
101+
102+
try {
103+
strictGson.fromJson(testString, type);
104+
fail();
105+
} catch (JsonSyntaxException expected) { }
45106
}
46107
}

gson/src/test/java/com/google/gson/functional/PrimitiveTest.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import com.google.gson.Gson;
2020
import com.google.gson.GsonBuilder;
21+
import com.google.gson.JsonIOException;
2122
import com.google.gson.JsonPrimitive;
2223
import com.google.gson.JsonSyntaxException;
2324
import com.google.gson.LongSerializationPolicy;
@@ -556,7 +557,7 @@ public void testUnquotedStringDeserializationFails() throws Exception {
556557
try {
557558
gson.fromJson(value, String.class);
558559
fail();
559-
} catch (JsonSyntaxException expected) { }
560+
} catch (JsonIOException expected) { }
560561
}
561562

562563
public void testHtmlCharacterSerialization() throws Exception {

0 commit comments

Comments
 (0)