Skip to content

Commit

Permalink
Check input end when parsing JSON
Browse files Browse the repository at this point in the history
Before this change, the end of input after reading a JSON value
was not properly validated:
- if there were remaining characters which did not parse as JSON,
  exception was thrown. E.g. `'["correct JSON"]and more'` failed
- if there were remaining characters which formed a valid token,
  they were silently ignored. E.g. `'["correct JSON"]{and more'`
  succeeded and returned `'["correct JSON"]'`

After this change, any trailing characters are caught and reported
as error.
  • Loading branch information
kasiafi committed Jan 27, 2022
1 parent ab93d28 commit a7bc2ba
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,11 @@ public void testInvalidJsonParse()
assertInvalidFunction("JSON 'INVALID'", INVALID_FUNCTION_ARGUMENT);
assertInvalidFunction("JSON_PARSE('INVALID')", INVALID_FUNCTION_ARGUMENT);
assertInvalidFunction("JSON_PARSE('\"x\": 1')", INVALID_FUNCTION_ARGUMENT);
assertInvalidFunction("JSON_PARSE('{}{')", INVALID_FUNCTION_ARGUMENT);
assertInvalidFunction("JSON_PARSE('{} \"a\"')", INVALID_FUNCTION_ARGUMENT);
assertInvalidFunction("JSON_PARSE('{}{abc')", INVALID_FUNCTION_ARGUMENT);
assertInvalidFunction("JSON_PARSE('{}abc')", INVALID_FUNCTION_ARGUMENT);
assertInvalidFunction("JSON_PARSE('')", INVALID_FUNCTION_ARGUMENT);
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3254,6 +3254,17 @@ public void testLiteral()
.hasErrorCode(INVALID_LITERAL);
}

@Test
public void testJsonLiteral()
{
// TODO All the below should fail. Literals should be validated during analysis https://github.com/trinodb/trino/issues/10719
analyze("SELECT JSON '{}{'");
analyze("SELECT JSON '{} \"a\"'");
analyze("SELECT JSON '{}{abc'");
analyze("SELECT JSON '{}abc'");
analyze("SELECT JSON ''");
}

@Test
public void testLambda()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,11 @@ public void testTypeConstructor()
assertFunction("JSON '[null]'", JSON, "[null]");
assertFunction("JSON '[13,null,42]'", JSON, "[13,null,42]");
assertFunction("JSON '{\"x\": null}'", JSON, "{\"x\":null}");
assertInvalidFunction("JSON '{}{'", INVALID_FUNCTION_ARGUMENT);
assertInvalidFunction("JSON '{} \"a\"'", INVALID_FUNCTION_ARGUMENT);
assertInvalidFunction("JSON '{}{abc'", INVALID_FUNCTION_ARGUMENT);
assertInvalidFunction("JSON '{}abc'", INVALID_FUNCTION_ARGUMENT);
assertInvalidFunction("JSON ''", INVALID_FUNCTION_ARGUMENT);
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@

import static com.fasterxml.jackson.core.JsonFactory.Feature.CANONICALIZE_FIELD_NAMES;
import static com.fasterxml.jackson.databind.SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS;
import static com.google.common.base.Preconditions.checkState;
import static io.trino.spi.StandardErrorCode.INVALID_FUNCTION_ARGUMENT;
import static java.lang.String.format;
import static java.nio.charset.StandardCharsets.UTF_8;
Expand All @@ -50,9 +51,11 @@ public static Slice jsonParse(Slice slice)
try (JsonParser parser = createJsonParser(JSON_FACTORY, slice)) {
SliceOutput output = new DynamicSliceOutput(slice.length());
SORTED_MAPPER.writeValue((OutputStream) output, SORTED_MAPPER.readValue(parser, Object.class));
// nextToken() returns null if the input is parsed correctly,
// but will throw an exception if there are trailing characters.
parser.nextToken();
// At this point, the end of input should be reached. nextToken() has three possible results:
// - null, if the end of the input was reached
// - token, if a correct JSON token is found (e.g. '{', 'null', '1')
// - exception, if there are characters which do not form a valid JSON token (e.g. 'abc')
checkState(parser.nextToken() == null, "Found characters after the expected end of input");
return output.slice();
}
catch (IOException | RuntimeException e) {
Expand Down

0 comments on commit a7bc2ba

Please sign in to comment.