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 eaed974527..8a15271df6 100644 --- a/gson/src/main/java/com/google/gson/stream/JsonReader.java +++ b/gson/src/main/java/com/google/gson/stream/JsonReader.java @@ -853,7 +853,7 @@ private int peekNumber() throws IOException { value = -(c - '0'); last = NUMBER_CHAR_DIGIT; } else if (last == NUMBER_CHAR_DIGIT) { - if (value == 0) { + if (fitsInLong && value == 0) { return PEEKED_NONE; // Leading '0' prefix is not allowed (since it could be octal). } long newValue = value * 10 - (c - '0'); diff --git a/gson/src/test/java/com/google/gson/stream/JsonReaderTest.java b/gson/src/test/java/com/google/gson/stream/JsonReaderTest.java index e7916ecf37..e8d546b577 100644 --- a/gson/src/test/java/com/google/gson/stream/JsonReaderTest.java +++ b/gson/src/test/java/com/google/gson/stream/JsonReaderTest.java @@ -820,6 +820,20 @@ public void testNumberWithOctalPrefix() throws IOException { assertStrictError(e, expectedLocation); } + /** + * Regression test for a bug where {@code peekNumber} rejected a valid numeric literal whose + * prefix happened to be a multiple of 264. The {@code long} accumulator wraps to + * exactly zero in that case, which the old "leading zero" guard misread as an octal prefix. + */ + @Test + public void testNumberLongAccumulatorOverflowsToZero() throws IOException { + String number = "184467440737095516160"; + JsonReader reader = new JsonReader(reader(number)); + reader.setStrictness(Strictness.STRICT); + assertThat(reader.peek()).isEqualTo(NUMBER); + assertThat(reader.nextString()).isEqualTo(number); + } + @Test public void testBooleans() throws IOException { JsonReader reader = new JsonReader(reader("[true,false]"));