Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue 1994 #2031

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Added validation for parsing integer types
Convert each integer type to a BigInteger to validate that the value is within the proper range, otherwise throw a NumberFormatException.

Added corresponding tests to JsonParserTest.
  • Loading branch information
dctrue2 authored and NatalieSty committed Dec 5, 2021
commit b8b3b518c34dd7b7d7a6157a45ed42de485f8d1d
29 changes: 28 additions & 1 deletion gson/src/main/java/com/google/gson/JsonPrimitive.java
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,14 @@ public float getAsFloat() {
*/
@Override
public long getAsLong() {

if (isNumber()) {
if (getAsBigInteger().compareTo(BigInteger.valueOf(Long.MAX_VALUE)) > 0)
{
throw new NumberFormatException("Expected a Long but was " + getAsNumber());
}
}

return isNumber() ? getAsNumber().longValue() : Long.parseLong(getAsString());
}

Expand All @@ -214,6 +222,14 @@ public long getAsLong() {
*/
@Override
public short getAsShort() {

if (isNumber()) {
if (getAsBigInteger().compareTo(BigInteger.valueOf(Short.MAX_VALUE)) > 0)
{
throw new NumberFormatException("Expected a Short but was " + getAsNumber());
}
}

return isNumber() ? getAsNumber().shortValue() : Short.parseShort(getAsString());
}

Expand All @@ -225,17 +241,28 @@ public short getAsShort() {
*/
@Override
public int getAsInt() {


if (isNumber()) {
if (getAsLong() > Integer.MAX_VALUE)
if (getAsBigInteger().compareTo(BigInteger.valueOf(Integer.MAX_VALUE)) > 0)
{
throw new NumberFormatException("Expected an Integer but was " + getAsNumber());
}
}

return isNumber() ? getAsNumber().intValue() : Integer.parseInt(getAsString());
}

@Override
public byte getAsByte() {

if (isNumber()) {
if (getAsBigInteger().compareTo(BigInteger.valueOf(Byte.MAX_VALUE)) > 0)
{
throw new NumberFormatException("Expected a Byte but was " + getAsNumber());
}
}

return isNumber() ? getAsNumber().byteValue() : Byte.parseByte(getAsString());
}

Expand Down
45 changes: 45 additions & 0 deletions gson/src/test/java/com/google/gson/JsonParserTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import java.io.CharArrayReader;
import java.io.CharArrayWriter;
import java.io.StringReader;
import java.math.BigInteger;

import junit.framework.TestCase;

Expand Down Expand Up @@ -98,6 +99,50 @@ public void testParseReader() {
assertEquals("c", e.getAsJsonObject().get("b").getAsString());
}

public void testParseLongToInt() {
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("foo", 10000000000L);

try {
jsonObject.get("foo").getAsInt();
fail();
} catch (NumberFormatException expected) {
}
}

public void testParseIntegerTypes() {

JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("bigInteger", BigInteger.valueOf(Long.MAX_VALUE).add(BigInteger.valueOf(200L)) );
jsonObject.addProperty("long", Integer.MAX_VALUE+143L);
jsonObject.addProperty("integer", Short.MAX_VALUE+32);
jsonObject.addProperty("short", Byte.MAX_VALUE+17);

try {
jsonObject.get("bigInteger").getAsLong();
fail("Big Integer should not parse as a Long");
} catch (NumberFormatException expected) {
}

try {
jsonObject.get("long").getAsInt();
fail("Long should not parse as an Integer");
} catch (NumberFormatException expected) {
}

try {
jsonObject.get("integer").getAsShort();
fail("Integer should not parse as a Short");
} catch (NumberFormatException expected) {
}

try {
jsonObject.get("short").getAsByte();
fail("Short should not parse as a Byte");
} catch (NumberFormatException expected) {
}
}

public void testReadWriteTwoObjects() throws Exception {
Gson gson = new Gson();
CharArrayWriter writer = new CharArrayWriter();
Expand Down