From e19672d0a394d552469147e12a70bf81413f0076 Mon Sep 17 00:00:00 2001 From: Jesse Wilson Date: Fri, 9 Sep 2011 05:04:24 +0000 Subject: [PATCH] Throw the right exceptions when primitives fail to parse. --- gson/GSON 2.0 NOTES.txt | 15 ++- .../internal/bind/BigDecimalTypeAdapter.java | 7 +- .../internal/bind/BigIntegerTypeAdapter.java | 7 +- .../gson/internal/bind/TypeAdapters.java | 27 ++++- .../google/gson/functional/PrimitiveTest.java | 107 +++++------------- 5 files changed, 78 insertions(+), 85 deletions(-) diff --git a/gson/GSON 2.0 NOTES.txt b/gson/GSON 2.0 NOTES.txt index b251b24d..f2d771bf 100644 --- a/gson/GSON 2.0 NOTES.txt +++ b/gson/GSON 2.0 NOTES.txt @@ -3,8 +3,21 @@ What's new in GSON 2.0 GSON 1.x used to automatically unwrap single-element arrays as necessary. GSON 2.x doesn't. com.google.gson.functional.ArrayTest.testSingleStringArrayDeserialization +com.google.gson.functional.PrimitiveTest#testPrimitiveIntegerAutoboxedInASingleElementArrayDeserialization +com.google.gson.functional.PrimitiveTest#testPrimitiveLongAutoboxedInASingleElementArrayDeserialization +com.google.gson.functional.PrimitiveTest#testPrimitiveBooleanAutoboxedDeserialization +com.google.gson.functional.PrimitiveTest.testPrimitiveBooleanAutoboxedInASingleElementArrayDeserialization +com.google.gson.functional.PrimitiveTest.testPrimitiveDoubleAutoboxedInASingleElementArrayDeserialization +com.google.gson.functional.PrimitiveTest.testBigDecimalInASingleElementArrayDeserialization +com.google.gson.functional.PrimitiveTest.testBigIntegerInASingleElementArrayDeserialization GSON 1.x permitted primitive types to be overridden GSON 2.x doesn't. -com.google.gson.functional.ArrayTest.testArrayOfPrimitivesWithCustomTypeAdapter \ No newline at end of file +com.google.gson.functional.ArrayTest.testArrayOfPrimitivesWithCustomTypeAdapter +com.google.gson.functional.PrimitiveTest.testOverridingDefaultPrimitiveSerialization + + +GSON 1.x rejects integers that have any fraction, even if it is ".0" +GSON 2.x permits integers to have ".0" fractions like "1.0" +com.google.gson.functional.PrimitiveTest.testDeserializingDecimalPointValuesAsIntegerFails \ No newline at end of file diff --git a/gson/src/main/java/com/google/gson/internal/bind/BigDecimalTypeAdapter.java b/gson/src/main/java/com/google/gson/internal/bind/BigDecimalTypeAdapter.java index 1d3d8301..30ea9ea7 100644 --- a/gson/src/main/java/com/google/gson/internal/bind/BigDecimalTypeAdapter.java +++ b/gson/src/main/java/com/google/gson/internal/bind/BigDecimalTypeAdapter.java @@ -16,6 +16,7 @@ package com.google.gson.internal.bind; +import com.google.gson.JsonSyntaxException; import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonWriter; @@ -31,7 +32,11 @@ public class BigDecimalTypeAdapter extends TypeAdapter { @Override public BigDecimal read(JsonReader reader) throws IOException { - return new BigDecimal(reader.nextString()); + try { + return new BigDecimal(reader.nextString()); + } catch (NumberFormatException e) { + throw new JsonSyntaxException(e); + } } @Override diff --git a/gson/src/main/java/com/google/gson/internal/bind/BigIntegerTypeAdapter.java b/gson/src/main/java/com/google/gson/internal/bind/BigIntegerTypeAdapter.java index 968cb8f6..9e0bfd98 100644 --- a/gson/src/main/java/com/google/gson/internal/bind/BigIntegerTypeAdapter.java +++ b/gson/src/main/java/com/google/gson/internal/bind/BigIntegerTypeAdapter.java @@ -16,6 +16,7 @@ package com.google.gson.internal.bind; +import com.google.gson.JsonSyntaxException; import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonWriter; @@ -31,7 +32,11 @@ public class BigIntegerTypeAdapter extends TypeAdapter { @Override public BigInteger read(JsonReader reader) throws IOException { - return new BigInteger(reader.nextString()); + try { + return new BigInteger(reader.nextString()); + } catch (NumberFormatException e) { + throw new JsonSyntaxException(e); + } } @Override diff --git a/gson/src/main/java/com/google/gson/internal/bind/TypeAdapters.java b/gson/src/main/java/com/google/gson/internal/bind/TypeAdapters.java index 1aa46d75..387839b6 100644 --- a/gson/src/main/java/com/google/gson/internal/bind/TypeAdapters.java +++ b/gson/src/main/java/com/google/gson/internal/bind/TypeAdapters.java @@ -16,6 +16,7 @@ package com.google.gson.internal.bind; +import com.google.gson.JsonSyntaxException; import com.google.gson.reflect.TypeToken; import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonToken; @@ -49,8 +50,12 @@ public final class TypeAdapters { public static final TypeAdapter BYTE = new TypeAdapter() { public Number read(JsonReader reader) throws IOException { - int intValue = reader.nextInt(); - return (byte) intValue; + try { + int intValue = reader.nextInt(); + return (byte) intValue; + } catch (NumberFormatException e) { + throw new JsonSyntaxException(e); + } } public void write(JsonWriter writer, Number value) throws IOException { writer.value(value); @@ -62,7 +67,11 @@ public final class TypeAdapters { public static final TypeAdapter SHORT = new TypeAdapter() { public Number read(JsonReader reader) throws IOException { - return (short) reader.nextInt(); + try { + return (short) reader.nextInt(); + } catch (NumberFormatException e) { + throw new JsonSyntaxException(e); + } } public void write(JsonWriter writer, Number value) throws IOException { writer.value(value); @@ -74,7 +83,11 @@ public final class TypeAdapters { public static final TypeAdapter INTEGER = new TypeAdapter() { public Number read(JsonReader reader) throws IOException { - return reader.nextInt(); + try { + return reader.nextInt(); + } catch (NumberFormatException e) { + throw new JsonSyntaxException(e); + } } public void write(JsonWriter writer, Number value) throws IOException { writer.value(value); @@ -86,7 +99,11 @@ public final class TypeAdapters { public static final TypeAdapter LONG = new TypeAdapter() { public Number read(JsonReader reader) throws IOException { - return reader.nextLong(); + try { + return reader.nextLong(); + } catch (NumberFormatException e) { + throw new JsonSyntaxException(e); + } } public void write(JsonWriter writer, Number value) throws IOException { writer.value(value); diff --git a/gson/src/test/java/com/google/gson/functional/PrimitiveTest.java b/gson/src/test/java/com/google/gson/functional/PrimitiveTest.java index 2695a7d3..65d080d5 100644 --- a/gson/src/test/java/com/google/gson/functional/PrimitiveTest.java +++ b/gson/src/test/java/com/google/gson/functional/PrimitiveTest.java @@ -86,15 +86,6 @@ public class PrimitiveTest extends TestCase { assertEquals("[-9332]", gson.toJson(target, Integer[].class)); } - public void testPrimitiveIntegerAutoboxedInASingleElementArrayDeserialization() { - int expected = 1; - int actual = gson.fromJson("[1]", int.class); - assertEquals(expected, actual); - - actual = gson.fromJson("[1]", Integer.class); - assertEquals(expected, actual); - } - public void testReallyLongValuesSerialization() { long value = 333961828784581L; assertEquals("333961828784581", gson.toJson(value)); @@ -127,24 +118,12 @@ public class PrimitiveTest extends TestCase { assertEquals("[-23]", gson.toJson(target, Long[].class)); } - public void testPrimitiveLongAutoboxedInASingleElementArrayDeserialization() { - long expected = 1L; - long actual = gson.fromJson("[1]", long.class); - assertEquals(expected, actual); - - actual = gson.fromJson("[1]", Long.class); - assertEquals(expected, actual); - } - public void testPrimitiveBooleanAutoboxedSerialization() { assertEquals("true", gson.toJson(true)); assertEquals("false", gson.toJson(false)); } - public void testPrimitiveBooleanAutoboxedDeserialization() { - assertEquals(Boolean.FALSE, gson.fromJson("[false]", Boolean.class)); - assertEquals(Boolean.TRUE, gson.fromJson("[true]", Boolean.class)); - + public void testBooleanDeserialization() { boolean value = gson.fromJson("false", boolean.class); assertEquals(false, value); value = gson.fromJson("true", boolean.class); @@ -158,16 +137,6 @@ public class PrimitiveTest extends TestCase { assertEquals("[false]", gson.toJson(target, Boolean[].class)); } - public void testPrimitiveBooleanAutoboxedInASingleElementArrayDeserialization() { - assertEquals(Boolean.FALSE, gson.fromJson("[false]", Boolean.class)); - assertEquals(Boolean.TRUE, gson.fromJson("[true]", Boolean.class)); - - boolean value = gson.fromJson("[false]", boolean.class); - assertEquals(false, value); - value = gson.fromJson("[true]", boolean.class); - assertEquals(true, value); - } - public void testNumberSerialization() { Number expected = 1L; String json = gson.toJson(expected); @@ -239,15 +208,6 @@ public class PrimitiveTest extends TestCase { assertEquals(expected.doubleValue(), actual1); } - public void testPrimitiveDoubleAutoboxedInASingleElementArrayDeserialization() { - double expected = -122.08; - double actual = gson.fromJson("[-122.08]", double.class); - assertEquals(expected, actual); - - actual = gson.fromJson("[-122.08]", Double.class); - assertEquals(expected, actual); - } - public void testBigDecimalSerialization() { BigDecimal target = new BigDecimal("-122.0e-21"); String json = gson.toJson(target); @@ -271,12 +231,6 @@ public class PrimitiveTest extends TestCase { assertEquals(target[0], new BigDecimal(actual)); } - public void testBigDecimalInASingleElementArrayDeserialization() { - BigDecimal expected = new BigDecimal("-122.08e-21"); - BigDecimal actual = gson.fromJson("[-122.08e-21]", BigDecimal.class); - assertEquals(expected, actual); - } - public void testSmallValueForBigDecimalSerialization() { BigDecimal target = new BigDecimal("1.55"); String actual = gson.toJson(target); @@ -341,12 +295,6 @@ public class PrimitiveTest extends TestCase { assertEquals(target[0], new BigInteger(actual)); } - public void testBigIntegerInASingleElementArrayDeserialization() { - BigInteger expected = new BigInteger("34343434343424242423432323243243242"); - BigInteger actual = gson.fromJson("[34343434343424242423432323243243242]", BigInteger.class); - assertEquals(expected, actual); - } - public void testSmallValueForBigIntegerSerialization() { BigInteger target = new BigInteger("15"); String actual = gson.toJson(target); @@ -363,7 +311,7 @@ public class PrimitiveTest extends TestCase { try { gson.fromJson("15.099", BigInteger.class); fail("BigInteger can not be decimal values."); - } catch (JsonParseException expected) { } + } catch (JsonSyntaxException expected) { } } public void testMoreSpecificSerialization() { @@ -376,20 +324,6 @@ public class PrimitiveTest extends TestCase { assertFalse(expectedJson.equals(actualJson)); } - public void testOverridingDefaultPrimitiveSerialization() { - CrazyLongTypeAdapter typeAdapter = new CrazyLongTypeAdapter(); - gson = new GsonBuilder() - .registerTypeAdapter(long.class, typeAdapter) - .registerTypeAdapter(Long.class, typeAdapter) - .create(); - long value = 1L; - String serializedValue = gson.toJson(value); - assertEquals(String.valueOf(value + CrazyLongTypeAdapter.DIFFERENCE), serializedValue); - - long deserializedValue = gson.fromJson(serializedValue, long.class); - assertEquals(value, deserializedValue); - } - private String extractElementFromArray(String json) { return json.substring(json.indexOf('[') + 1, json.indexOf(']')); } @@ -450,7 +384,7 @@ public class PrimitiveTest extends TestCase { try { gson.fromJson("NaN", BigDecimal.class); fail("Gson should not accept NaN for deserialization by default."); - } catch (JsonParseException expected) { + } catch (JsonSyntaxException expected) { } } @@ -510,7 +444,7 @@ public class PrimitiveTest extends TestCase { try { gson.fromJson("Infinity", BigDecimal.class); fail("Gson should not accept positive infinity for deserialization with BigDecimal"); - } catch (JsonParseException expected) { + } catch (JsonSyntaxException expected) { } } @@ -570,7 +504,7 @@ public class PrimitiveTest extends TestCase { try { gson.fromJson("-Infinity", BigDecimal.class); fail("Gson should not accept positive infinity for deserialization"); - } catch (JsonParseException expected) { + } catch (JsonSyntaxException expected) { } } @@ -778,11 +712,30 @@ public class PrimitiveTest extends TestCase { } catch (JsonSyntaxException expected) {} } - public void testDeserializingDecimalPointValuesAsIntegerFails() { + public void testDeserializingDecimalPointValueZeroSucceeds() { + assertEquals(1, (int) gson.fromJson("1.0", Integer.class)); + } + + public void testDeserializingNonZeroDecimalPointValuesAsIntegerFails() { try { - gson.fromJson("1.0", Integer.class); + gson.fromJson("1.02", Byte.class); fail(); - } catch (JsonParseException expected) { + } catch (JsonSyntaxException expected) { + } + try { + gson.fromJson("1.02", Short.class); + fail(); + } catch (JsonSyntaxException expected) { + } + try { + gson.fromJson("1.02", Integer.class); + fail(); + } catch (JsonSyntaxException expected) { + } + try { + gson.fromJson("1.02", Long.class); + fail(); + } catch (JsonSyntaxException expected) { } } @@ -790,7 +743,7 @@ public class PrimitiveTest extends TestCase { try { gson.fromJson("-122.08e-213", Integer.class); fail(); - } catch (JsonParseException expected) { + } catch (JsonSyntaxException expected) { } } @@ -812,7 +765,7 @@ public class PrimitiveTest extends TestCase { try { gson.fromJson("-122.08e-2132", long.class); fail(); - } catch (JsonParseException expected) { + } catch (JsonSyntaxException expected) { } } @@ -832,7 +785,7 @@ public class PrimitiveTest extends TestCase { try { gson.fromJson("-122.08e-213", BigInteger.class); fail(); - } catch (JsonParseException expected) { + } catch (JsonSyntaxException expected) { } }