Don't return null on an unexpected EOF unless the document is empty. This brings us back to compatibility with GSON 1.5.

This commit is contained in:
Jesse Wilson 2010-11-08 19:16:05 +00:00
parent 4d0cd67cde
commit 103edb9c36
2 changed files with 61 additions and 37 deletions

View File

@ -17,9 +17,8 @@
package com.google.gson; package com.google.gson;
import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonReader;
import com.google.gson.stream.MalformedJsonException;
import com.google.gson.stream.JsonWriter; import com.google.gson.stream.JsonWriter;
import com.google.gson.stream.MalformedJsonException;
import java.io.EOFException; import java.io.EOFException;
import java.io.IOException; import java.io.IOException;
import java.io.Writer; import java.io.Writer;
@ -34,43 +33,21 @@ final class Streams {
* Takes a reader in any state and returns the next value as a JsonElement. * Takes a reader in any state and returns the next value as a JsonElement.
*/ */
static JsonElement parse(JsonReader reader) throws JsonParseException { static JsonElement parse(JsonReader reader) throws JsonParseException {
boolean isEmpty = true;
try { try {
switch (reader.peek()) { reader.peek();
case STRING: isEmpty = false;
return new JsonPrimitive(reader.nextString()); return parseRecursive(reader);
case NUMBER:
String number = reader.nextString();
return new JsonPrimitive(JsonPrimitive.stringToNumber(number));
case BOOLEAN:
return new JsonPrimitive(reader.nextBoolean());
case NULL:
reader.nextNull();
return JsonNull.createJsonNull();
case BEGIN_ARRAY:
JsonArray array = new JsonArray();
reader.beginArray();
while (reader.hasNext()) {
array.add(parse(reader));
}
reader.endArray();
return array;
case BEGIN_OBJECT:
JsonObject object = new JsonObject();
reader.beginObject();
while (reader.hasNext()) {
object.add(reader.nextName(), parse(reader));
}
reader.endObject();
return object;
case END_DOCUMENT:
case NAME:
case END_OBJECT:
case END_ARRAY:
default:
throw new IllegalArgumentException();
}
} catch (EOFException e) { } catch (EOFException e) {
return JsonNull.createJsonNull(); /*
* For compatibility with JSON 1.5 and earlier, we return a JsonNull for
* empty documents instead of throwing.
*/
if (isEmpty) {
return JsonNull.createJsonNull();
} else {
throw new JsonIOException(e);
}
} catch (MalformedJsonException e) { } catch (MalformedJsonException e) {
throw new JsonSyntaxException(e); throw new JsonSyntaxException(e);
} catch (IOException e) { } catch (IOException e) {
@ -80,6 +57,43 @@ final class Streams {
} }
} }
private static JsonElement parseRecursive(JsonReader reader) throws IOException {
switch (reader.peek()) {
case STRING:
return new JsonPrimitive(reader.nextString());
case NUMBER:
String number = reader.nextString();
return new JsonPrimitive(JsonPrimitive.stringToNumber(number));
case BOOLEAN:
return new JsonPrimitive(reader.nextBoolean());
case NULL:
reader.nextNull();
return JsonNull.createJsonNull();
case BEGIN_ARRAY:
JsonArray array = new JsonArray();
reader.beginArray();
while (reader.hasNext()) {
array.add(parseRecursive(reader));
}
reader.endArray();
return array;
case BEGIN_OBJECT:
JsonObject object = new JsonObject();
reader.beginObject();
while (reader.hasNext()) {
object.add(reader.nextName(), parseRecursive(reader));
}
reader.endObject();
return object;
case END_DOCUMENT:
case NAME:
case END_OBJECT:
case END_ARRAY:
default:
throw new IllegalArgumentException();
}
}
/** /**
* Writes the JSON element to the writer, recursively. * Writes the JSON element to the writer, recursively.
*/ */

View File

@ -20,6 +20,7 @@ import com.google.gson.Gson;
import com.google.gson.GsonBuilder; import com.google.gson.GsonBuilder;
import com.google.gson.InstanceCreator; import com.google.gson.InstanceCreator;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.common.TestTypes.ArrayOfObjects; import com.google.gson.common.TestTypes.ArrayOfObjects;
import com.google.gson.common.TestTypes.BagOfPrimitiveWrappers; import com.google.gson.common.TestTypes.BagOfPrimitiveWrappers;
import com.google.gson.common.TestTypes.BagOfPrimitives; import com.google.gson.common.TestTypes.BagOfPrimitives;
@ -30,6 +31,7 @@ import com.google.gson.common.TestTypes.ClassWithTransientFields;
import com.google.gson.common.TestTypes.Nested; import com.google.gson.common.TestTypes.Nested;
import com.google.gson.common.TestTypes.PrimitiveArray; import com.google.gson.common.TestTypes.PrimitiveArray;
import com.google.gson.reflect.TypeToken;
import java.util.List; import java.util.List;
import junit.framework.TestCase; import junit.framework.TestCase;
@ -145,6 +147,14 @@ public class ObjectTest extends TestCase {
assertNull(object); assertNull(object);
} }
public void testTruncatedDeserialization() {
try {
gson.fromJson("[\"a\", \"b\",", new TypeToken<List<String>>() {}.getType());
fail();
} catch (JsonParseException expected) {
}
}
public void testNullDeserialization() throws Exception { public void testNullDeserialization() throws Exception {
String myNullObject = null; String myNullObject = null;
Object object = gson.fromJson(myNullObject, Object.class); Object object = gson.fromJson(myNullObject, Object.class);