diff --git a/gson/src/main/java/com/google/gson/Gson.java b/gson/src/main/java/com/google/gson/Gson.java index 62d5ca867d..666e5f8bd3 100644 --- a/gson/src/main/java/com/google/gson/Gson.java +++ b/gson/src/main/java/com/google/gson/Gson.java @@ -16,25 +16,6 @@ package com.google.gson; -import java.io.EOFException; -import java.io.IOException; -import java.io.Reader; -import java.io.StringReader; -import java.io.StringWriter; -import java.io.Writer; -import java.lang.reflect.Type; -import java.math.BigDecimal; -import java.math.BigInteger; -import java.text.DateFormat; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.atomic.AtomicLong; -import java.util.concurrent.atomic.AtomicLongArray; - import com.google.gson.internal.ConstructorConstructor; import com.google.gson.internal.Excluder; import com.google.gson.internal.GsonBuildConfig; @@ -58,6 +39,24 @@ import com.google.gson.stream.JsonToken; import com.google.gson.stream.JsonWriter; import com.google.gson.stream.MalformedJsonException; +import java.io.EOFException; +import java.io.IOException; +import java.io.Reader; +import java.io.StringReader; +import java.io.StringWriter; +import java.io.Writer; +import java.lang.reflect.Type; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.text.DateFormat; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicLong; +import java.util.concurrent.atomic.AtomicLongArray; /** * This is the main class for using Gson. Gson is typically used by first constructing a @@ -97,6 +96,33 @@ *
See the Gson User Guide * for a more complete set of examples.
* + *The JSON data is written in {@linkplain JsonWriter#setLenient(boolean) lenient mode}, + * regardless of the lenient mode setting of the provided writer. The lenient mode setting + * of the writer is restored once this method returns. + * + *
The 'HTML-safe' and 'serialize {@code null}' settings of this {@code Gson} instance + * (configured by the {@link GsonBuilder}) are applied, and the original settings of the + * writer are restored once this method returns. + * * @throws JsonIOException if there was a problem writing to the writer */ @SuppressWarnings("unchecked") @@ -834,6 +869,15 @@ public JsonReader newJsonReader(Reader reader) { /** * Writes the JSON for {@code jsonElement} to {@code writer}. + * + *
The JSON data is written in {@linkplain JsonWriter#setLenient(boolean) lenient mode}, + * regardless of the lenient mode setting of the provided writer. The lenient mode setting + * of the writer is restored once this method returns. + * + *
The 'HTML-safe' and 'serialize {@code null}' settings of this {@code Gson} instance + * (configured by the {@link GsonBuilder}) are applied, and the original settings of the + * writer are restored once this method returns. + * * @throws JsonIOException if there was a problem writing to the writer */ public void toJson(JsonElement jsonElement, JsonWriter writer) throws JsonIOException { @@ -868,6 +912,9 @@ public void toJson(JsonElement jsonElement, JsonWriter writer) throws JsonIOExce * {@link #fromJson(String, Type)}. If you have the Json in a {@link Reader} instead of * a String, use {@link #fromJson(Reader, Class)} instead. * + *
An exception is thrown if the JSON string has multiple top-level JSON elements,
+ * or if there is trailing data.
+ *
* @param An exception is thrown if the JSON string has multiple top-level JSON elements,
+ * or if there is trailing data.
+ *
* @param An exception is thrown if the JSON data has multiple top-level JSON elements,
+ * or if there is trailing data.
+ *
* @param An exception is thrown if the JSON data has multiple top-level JSON elements,
+ * or if there is trailing data.
+ *
* @param Unlike the other {@code fromJson} methods, no exception is thrown if the JSON data has
+ * multiple top-level JSON elements, or if there is trailing data.
+ *
+ * The JSON data is parsed in {@linkplain JsonReader#setLenient(boolean) lenient mode},
+ * regardless of the lenient mode setting of the provided reader. The lenient mode setting
+ * of the reader is restored once this method returns.
*
* @throws JsonIOException if there was a problem writing to the Reader
* @throws JsonSyntaxException if json is not a valid representation for an object of type
diff --git a/gson/src/main/java/com/google/gson/GsonBuilder.java b/gson/src/main/java/com/google/gson/GsonBuilder.java
index 5e77ac0cb1..4c540ac1c2 100644
--- a/gson/src/main/java/com/google/gson/GsonBuilder.java
+++ b/gson/src/main/java/com/google/gson/GsonBuilder.java
@@ -34,6 +34,7 @@
import com.google.gson.internal.sql.SqlTypesSupport;
import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonWriter;
import static com.google.gson.Gson.DEFAULT_COMPLEX_MAP_KEYS;
import static com.google.gson.Gson.DEFAULT_DATE_PATTERN;
@@ -425,12 +426,14 @@ public GsonBuilder setPrettyPrinting() {
}
/**
- * By default, Gson is strict and only accepts JSON as specified by
- * RFC 4627. This option makes the parser
- * liberal in what it accepts.
+ * Configures Gson to allow JSON data which does not strictly comply with the JSON specification.
+ *
+ * Note: Due to legacy reasons most methods of Gson are always lenient, regardless of
+ * whether this builder method is used.
*
* @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
* @see JsonReader#setLenient(boolean)
+ * @see JsonWriter#setLenient(boolean)
*/
public GsonBuilder setLenient() {
lenient = true;
diff --git a/gson/src/main/java/com/google/gson/JsonParser.java b/gson/src/main/java/com/google/gson/JsonParser.java
index 5121e4e10a..d3508c1073 100644
--- a/gson/src/main/java/com/google/gson/JsonParser.java
+++ b/gson/src/main/java/com/google/gson/JsonParser.java
@@ -15,17 +15,16 @@
*/
package com.google.gson;
-import java.io.IOException;
-import java.io.Reader;
-import java.io.StringReader;
-
import com.google.gson.internal.Streams;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.MalformedJsonException;
+import java.io.IOException;
+import java.io.Reader;
+import java.io.StringReader;
/**
- * A parser to parse Json into a parse tree of {@link JsonElement}s
+ * A parser to parse JSON into a parse tree of {@link JsonElement}s.
*
* @author Inderjeet Singh
* @author Joel Leitch
@@ -37,7 +36,11 @@ public final class JsonParser {
public JsonParser() {}
/**
- * Parses the specified JSON string into a parse tree
+ * Parses the specified JSON string into a parse tree.
+ * An exception is thrown if the JSON string has multiple top-level JSON elements,
+ * or if there is trailing data.
+ *
+ * The JSON string is parsed in {@linkplain JsonReader#setLenient(boolean) lenient mode}.
*
* @param json JSON text
* @return a parse tree of {@link JsonElement}s corresponding to the specified JSON
@@ -48,11 +51,16 @@ public static JsonElement parseString(String json) throws JsonSyntaxException {
}
/**
- * Parses the specified JSON string into a parse tree
+ * Parses the complete JSON string provided by the reader into a parse tree.
+ * An exception is thrown if the JSON string has multiple top-level JSON elements,
+ * or if there is trailing data.
+ *
+ * The JSON data is parsed in {@linkplain JsonReader#setLenient(boolean) lenient mode}.
*
* @param reader JSON text
* @return a parse tree of {@link JsonElement}s corresponding to the specified JSON
- * @throws JsonParseException if the specified text is not valid JSON
+ * @throws JsonParseException if there is an IOException or if the specified
+ * text is not valid JSON
*/
public static JsonElement parseReader(Reader reader) throws JsonIOException, JsonSyntaxException {
try {
@@ -73,6 +81,12 @@ public static JsonElement parseReader(Reader reader) throws JsonIOException, Jso
/**
* Returns the next value from the JSON stream as a parse tree.
+ * Unlike the other {@code parse} methods, no exception is thrown if the JSON data has
+ * multiple top-level JSON elements, or if there is trailing data.
+ *
+ * The JSON data is parsed in {@linkplain JsonReader#setLenient(boolean) lenient mode},
+ * regardless of the lenient mode setting of the provided reader. The lenient mode setting
+ * of the reader is restored once this method returns.
*
* @throws JsonParseException if there is an IOException or if the specified
* text is not valid JSON
diff --git a/gson/src/main/java/com/google/gson/TypeAdapter.java b/gson/src/main/java/com/google/gson/TypeAdapter.java
index 4646d271d7..ba798537be 100644
--- a/gson/src/main/java/com/google/gson/TypeAdapter.java
+++ b/gson/src/main/java/com/google/gson/TypeAdapter.java
@@ -16,8 +16,8 @@
package com.google.gson;
-import com.google.gson.internal.bind.JsonTreeWriter;
import com.google.gson.internal.bind.JsonTreeReader;
+import com.google.gson.internal.bind.JsonTreeWriter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;
@@ -252,6 +252,9 @@ public final JsonElement toJsonTree(T value) {
* read is strict. Create a {@link JsonReader#setLenient(boolean) lenient}
* {@code JsonReader} and call {@link #read(JsonReader)} for lenient reading.
*
+ * No exception is thrown if the JSON data has multiple top-level JSON elements,
+ * or if there is trailing data.
+ *
* @return the converted Java object. May be null.
* @since 2.2
*/
@@ -266,6 +269,9 @@ public final T fromJson(Reader in) throws IOException {
* strict. Create a {@link JsonReader#setLenient(boolean) lenient} {@code
* JsonReader} and call {@link #read(JsonReader)} for lenient reading.
*
+ * No exception is thrown if the JSON data has multiple top-level JSON elements,
+ * or if there is trailing data.
+ *
* @return the converted Java object. May be null.
* @since 2.2
*/
@@ -276,7 +282,8 @@ public final T fromJson(String json) throws IOException {
/**
* Converts {@code jsonTree} to a Java object.
*
- * @param jsonTree the Java object to convert. May be {@link JsonNull}.
+ * @param jsonTree the JSON element to convert. May be {@link JsonNull}.
+ * @return the converted Java object. May be null.
* @since 2.2
*/
public final T fromJsonTree(JsonElement jsonTree) {
diff --git a/gson/src/main/java/com/google/gson/stream/JsonReader.java b/gson/src/main/java/com/google/gson/stream/JsonReader.java
index 2984d19c19..6cb820bef7 100644
--- a/gson/src/main/java/com/google/gson/stream/JsonReader.java
+++ b/gson/src/main/java/com/google/gson/stream/JsonReader.java
@@ -304,8 +304,6 @@ public JsonReader(Reader in) {
* prefix, Note: Even in strict mode there are slight derivations from the JSON
+ * specification:
+ * ")]}'\n"
.
*
+ *
*/
public final void setLenient(boolean lenient) {
this.lenient = lenient;
diff --git a/gson/src/test/java/com/google/gson/TypeAdapterTest.java b/gson/src/test/java/com/google/gson/TypeAdapterTest.java
new file mode 100644
index 0000000000..ab44637393
--- /dev/null
+++ b/gson/src/test/java/com/google/gson/TypeAdapterTest.java
@@ -0,0 +1,52 @@
+package com.google.gson;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonWriter;
+import java.io.IOException;
+import java.io.StringReader;
+import org.junit.Test;
+
+public class TypeAdapterTest {
+ @Test
+ public void testNullSafe() throws IOException {
+ TypeAdapter\LF
(with {@code LF}
+ * being the Unicode character U+000A), resulting in a {@code LF} within the
+ * read JSON string
+ *