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;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.MalformedJsonException;
import com.google.gson.stream.JsonWriter;
import com.google.gson.stream.MalformedJsonException;
import java.io.EOFException;
import java.io.IOException;
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.
*/
static JsonElement parse(JsonReader reader) throws JsonParseException {
boolean isEmpty = true;
try {
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(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();
}
reader.peek();
isEmpty = false;
return parseRecursive(reader);
} 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) {
throw new JsonSyntaxException(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.
*/

View File

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