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

fix: GSON parser now throws IOException on invalid JSON input #1355

Merged
merged 6 commits into from Aug 26, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 0 additions & 5 deletions google-http-client-gson/pom.xml
Expand Up @@ -81,10 +81,5 @@
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Expand Up @@ -17,7 +17,6 @@
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.JsonParser;
import com.google.api.client.json.JsonToken;
import com.google.api.client.util.Preconditions;
import com.google.gson.stream.JsonReader;
import java.io.EOFException;
import java.io.IOException;
Expand All @@ -44,8 +43,7 @@ class GsonParser extends JsonParser {
GsonParser(GsonFactory factory, JsonReader reader) {
this.factory = factory;
this.reader = reader;
// lenient to allow top-level values of any type
reader.setLenient(true);
reader.setLenient(false);
}

@Override
Expand All @@ -69,56 +67,58 @@ public JsonFactory getFactory() {
}

@Override
public byte getByteValue() {
public byte getByteValue() throws IOException {
checkNumber();
return Byte.parseByte(currentText);
}

@Override
public short getShortValue() {
public short getShortValue() throws IOException {
checkNumber();
return Short.parseShort(currentText);
}

@Override
public int getIntValue() {
public int getIntValue() throws IOException {
checkNumber();
return Integer.parseInt(currentText);
}

@Override
public float getFloatValue() {
public float getFloatValue() throws IOException {
checkNumber();
return Float.parseFloat(currentText);
}

@Override
public BigInteger getBigIntegerValue() {
public BigInteger getBigIntegerValue() throws IOException {
checkNumber();
return new BigInteger(currentText);
}

@Override
public BigDecimal getDecimalValue() {
public BigDecimal getDecimalValue() throws IOException {
checkNumber();
return new BigDecimal(currentText);
}

@Override
public double getDoubleValue() {
public double getDoubleValue() throws IOException {
checkNumber();
return Double.parseDouble(currentText);
}

@Override
public long getLongValue() {
public long getLongValue() throws IOException {
checkNumber();
return Long.parseLong(currentText);
}

private void checkNumber() {
Preconditions.checkArgument(
currentToken == JsonToken.VALUE_NUMBER_INT || currentToken == JsonToken.VALUE_NUMBER_FLOAT);
private void checkNumber() throws IOException {
if (currentToken != JsonToken.VALUE_NUMBER_INT
&& currentToken != JsonToken.VALUE_NUMBER_FLOAT) {
throw new IOException("Token is not a number");
}
}

@Override
Expand Down
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2010 Google Inc.
* Copyright 2010 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
Expand All @@ -17,8 +17,7 @@
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.JsonParser;
import com.google.api.client.test.json.AbstractJsonFactoryTest;
import com.google.common.base.Charsets;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.ArrayList;

/**
Expand Down Expand Up @@ -80,10 +79,19 @@ public final void testToPrettyString_Feed() throws Exception {
assertEquals(JSON_FEED_PRETTY, newFactory().toPrettyString(feed));
}

public final void testParse_directValue() throws Exception {
byte[] jsonData = Charsets.UTF_8.encode("123").array();
JsonParser jp =
newFactory().createJsonParser(new ByteArrayInputStream(jsonData), Charsets.UTF_8);
assertEquals(123, jp.parse(Integer.class, true));
public final void testParse_directValue() throws IOException {
JsonParser parser = newFactory().createJsonParser("123");
assertEquals(123, parser.parse(Integer.class, true));
}

public final void testGetByteValue() throws IOException {
JsonParser parser = newFactory().createJsonParser("123");

try {
parser.getByteValue();
fail("should throw IOException");
} catch (IOException ex) {
assertNotNull(ex.getMessage());
}
}
}
5 changes: 0 additions & 5 deletions google-http-client-jackson2/pom.xml
Expand Up @@ -80,10 +80,5 @@
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012 Google Inc.
* Copyright 2012 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
Expand All @@ -18,8 +18,7 @@
import com.google.api.client.json.JsonParser;
import com.google.api.client.test.json.AbstractJsonFactoryTest;
import com.google.api.client.util.StringUtils;
import com.google.common.base.Charsets;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.ArrayList;

/**
Expand Down Expand Up @@ -74,9 +73,18 @@ public final void testToPrettyString_Feed() throws Exception {
}

public final void testParse_directValue() throws Exception {
byte[] jsonData = Charsets.UTF_8.encode("123").array();
JsonParser jp =
newFactory().createJsonParser(new ByteArrayInputStream(jsonData), Charsets.UTF_8);
assertEquals(123, jp.parse(Integer.class, true));
JsonParser parser = newFactory().createJsonParser("123");
assertEquals(123, parser.parse(Integer.class, true));
}

public final void testGetByteValue() throws IOException {
JsonParser parser = newFactory().createJsonParser("123");

try {
parser.getByteValue();
fail("should throw IOException");
} catch (IOException ex) {
assertNotNull(ex.getMessage());
}
}
}
Expand Up @@ -22,6 +22,7 @@
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import junit.framework.TestCase;
import org.junit.Assert;

public abstract class AbstractJsonParserTest extends TestCase {

Expand All @@ -44,6 +45,29 @@ public void testParse_basic() throws IOException {
assertEquals(Boolean.FALSE, json.get("boolValue"));
}

public void testGetWrongType() throws IOException {
JsonObjectParser parser = new JsonObjectParser(newJsonFactory());
InputStream inputStream = new ByteArrayInputStream(TEST_JSON.getBytes(StandardCharsets.UTF_8));
GenericJson json = parser.parseAndClose(inputStream, StandardCharsets.UTF_8, GenericJson.class);
assertTrue(json.get("strValue") instanceof String);
assertEquals("bar", json.get("strValue"));
assertTrue(json.get("intValue") instanceof BigDecimal);
assertEquals(new BigDecimal(123), json.get("intValue"));
assertTrue(json.get("boolValue") instanceof Boolean);
assertEquals(Boolean.FALSE, json.get("boolValue"));
}

public void testParse_badJson() throws IOException {
JsonObjectParser parser = new JsonObjectParser(newJsonFactory());
InputStream inputStream = new ByteArrayInputStream("not json".getBytes(StandardCharsets.UTF_8));
try {
parser.parseAndClose(inputStream, StandardCharsets.UTF_8, GenericJson.class);
fail("Malformed JSON not detected");
} catch (IOException ex) {
Assert.assertNotNull(ex.getMessage());
}
}

public void testParse_bigDecimal() throws IOException {
JsonObjectParser parser = new JsonObjectParser(newJsonFactory());
InputStream inputStream =
Expand Down