Trim whitespace in BasicJsonParser

Previously, whitespace in between the keys and values in the JSON was
not trimmed correctly in BasicJsonParser which lead to it incorrectly
parsing JSON with whitespace between the opening of a list ([) and the
opening of a map ({).

This commit updates the parser to trim unwanted whitespace and adds a
test to AbstractJsonParserTests to verify the whitespace handling
behaviour across all JsonParser implementations.

Closes gh-18911
This commit is contained in:
Andy Wilkinson 2019-11-07 09:52:08 +00:00
parent d1ead884c4
commit a11661d284
2 changed files with 14 additions and 3 deletions

View File

@ -49,7 +49,7 @@ public class BasicJsonParser extends AbstractJsonParser {
private List<Object> parseListInternal(String json) {
List<Object> list = new ArrayList<>();
json = trimLeadingCharacter(trimTrailingCharacter(json, ']'), '[');
json = trimLeadingCharacter(trimTrailingCharacter(json, ']'), '[').trim();
for (String value : tokenize(json)) {
list.add(parseInternal(value));
}
@ -97,7 +97,7 @@ public class BasicJsonParser extends AbstractJsonParser {
private Map<String, Object> parseMapInternal(String json) {
Map<String, Object> map = new LinkedHashMap<>();
json = trimLeadingCharacter(trimTrailingCharacter(json, '}'), '{');
json = trimLeadingCharacter(trimTrailingCharacter(json, '}'), '{').trim();
for (String pair : tokenize(json)) {
String[] values = StringUtils.trimArrayElements(StringUtils.split(pair, ":"));
String key = trimLeadingCharacter(trimTrailingCharacter(values[0], '"'), '"');
@ -151,7 +151,7 @@ public class BasicJsonParser extends AbstractJsonParser {
index++;
}
if (build.length() > 0) {
list.add(build.toString());
list.add(build.toString().trim());
}
return list;
}

View File

@ -101,6 +101,17 @@ public abstract class AbstractJsonParserTests {
.parseMap("{\"foo\":[{\"foo\":\"bar\",\"spam\":1},{\"foo\":\"baz\",\"spam\":2}]}");
assertThat(map).hasSize(1);
assertThat(((List<Object>) map.get("foo"))).hasSize(2);
assertThat(map.get("foo")).asList().allMatch(Map.class::isInstance);
}
@SuppressWarnings("unchecked")
@Test
public void nestedLeadingAndTrailingWhitespace() {
Map<String, Object> map = this.parser.parseMap(
" {\"foo\": [ { \"foo\" : \"bar\" , \"spam\" : 1 } , { \"foo\" : \"baz\" , \"spam\" : 2 } ] } ");
assertThat(map).hasSize(1);
assertThat(((List<Object>) map.get("foo"))).hasSize(2);
assertThat(map.get("foo")).asList().allMatch(Map.class::isInstance);
}
@Test