From a11661d284f7951659fcd1370831eddca06a7dac Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Thu, 7 Nov 2019 09:52:08 +0000 Subject: [PATCH] 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 --- .../springframework/boot/json/BasicJsonParser.java | 6 +++--- .../boot/json/AbstractJsonParserTests.java | 11 +++++++++++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/json/BasicJsonParser.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/json/BasicJsonParser.java index 7bfaf0997f3..b24f98e36a0 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/json/BasicJsonParser.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/json/BasicJsonParser.java @@ -49,7 +49,7 @@ public class BasicJsonParser extends AbstractJsonParser { private List parseListInternal(String json) { List 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 parseMapInternal(String json) { Map 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; } diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/json/AbstractJsonParserTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/json/AbstractJsonParserTests.java index fa6d9d0d47d..43cecfe5517 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/json/AbstractJsonParserTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/json/AbstractJsonParserTests.java @@ -101,6 +101,17 @@ public abstract class AbstractJsonParserTests { .parseMap("{\"foo\":[{\"foo\":\"bar\",\"spam\":1},{\"foo\":\"baz\",\"spam\":2}]}"); assertThat(map).hasSize(1); assertThat(((List) map.get("foo"))).hasSize(2); + assertThat(map.get("foo")).asList().allMatch(Map.class::isInstance); + } + + @SuppressWarnings("unchecked") + @Test + public void nestedLeadingAndTrailingWhitespace() { + Map map = this.parser.parseMap( + " {\"foo\": [ { \"foo\" : \"bar\" , \"spam\" : 1 } , { \"foo\" : \"baz\" , \"spam\" : 2 } ] } "); + assertThat(map).hasSize(1); + assertThat(((List) map.get("foo"))).hasSize(2); + assertThat(map.get("foo")).asList().allMatch(Map.class::isInstance); } @Test