Repository: cxf Updated Branches: refs/heads/master 0a4e29637 -> f8a3ab807
[CXF-7496] Avoiding indexOf searches Project: http://git-wip-us.apache.org/repos/asf/cxf/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/8d485322 Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/8d485322 Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/8d485322 Branch: refs/heads/master Commit: 8d4853224628c236be5cc041cfb9cc54ca7837db Parents: 3b80034 Author: Sergey Beryozkin <sberyoz...@gmail.com> Authored: Tue Sep 5 16:31:54 2017 +0100 Committer: Sergey Beryozkin <sberyoz...@gmail.com> Committed: Tue Sep 5 16:31:54 2017 +0100 ---------------------------------------------------------------------- .../json/basic/JsonMapObjectReaderWriter.java | 47 +++++++++------- .../basic/JsonMapObjectReaderWriterTest.java | 56 ++++++++++++++++++++ 2 files changed, 84 insertions(+), 19 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf/blob/8d485322/rt/rs/extensions/json-basic/src/main/java/org/apache/cxf/jaxrs/json/basic/JsonMapObjectReaderWriter.java ---------------------------------------------------------------------- diff --git a/rt/rs/extensions/json-basic/src/main/java/org/apache/cxf/jaxrs/json/basic/JsonMapObjectReaderWriter.java b/rt/rs/extensions/json-basic/src/main/java/org/apache/cxf/jaxrs/json/basic/JsonMapObjectReaderWriter.java index 4e87d78..f3f176c 100644 --- a/rt/rs/extensions/json-basic/src/main/java/org/apache/cxf/jaxrs/json/basic/JsonMapObjectReaderWriter.java +++ b/rt/rs/extensions/json-basic/src/main/java/org/apache/cxf/jaxrs/json/basic/JsonMapObjectReaderWriter.java @@ -42,6 +42,7 @@ public class JsonMapObjectReaderWriter { private static final char OBJECT_END = '}'; private static final char ARRAY_START = '['; private static final char ARRAY_END = ']'; + private static final char ESCAPE = '\\'; private static final String NULL_VALUE = "null"; private boolean format; @@ -197,7 +198,7 @@ public class JsonMapObjectReaderWriter { values.put(name, internalFromJsonAsList(name, newJson)); i = closingIndex + 1; } else { - int commaIndex = getCommaIndex(json, sepIndex + j, sepIndex + j); + int commaIndex = getCommaIndex(json, sepIndex + j); Object value = readPrimitiveValue(name, json, sepIndex + j, commaIndex); values.put(name, value); i = commaIndex + 1; @@ -218,7 +219,7 @@ public class JsonMapObjectReaderWriter { values.add(nextMap.map); i = closingIndex + 1; } else { - int commaIndex = getCommaIndex(json, i, i); + int commaIndex = getCommaIndex(json, i); Object value = readPrimitiveValue(name, json, i, commaIndex); values.add(value); i = commaIndex; @@ -246,33 +247,41 @@ public class JsonMapObjectReaderWriter { return value; } - protected static int getCommaIndex(String json, int start, int from) { - int commaIndex = json.indexOf(COMMA, from); + protected static int getCommaIndex(String json, int from) { + int commaIndex = getNextSepCharIndex(json, COMMA, from); if (commaIndex == -1) { commaIndex = json.length(); - } else if (json.charAt(commaIndex - 1) != DQUOTE && json.charAt(start) == DQUOTE) { - int lastNonWhiteCharIndex = commaIndex - 1; - for (; lastNonWhiteCharIndex > from; lastNonWhiteCharIndex--) { - if (!Character.isWhitespace(json.charAt(lastNonWhiteCharIndex))) { - break; - } - } - if (json.charAt(lastNonWhiteCharIndex) != DQUOTE) { - commaIndex = getCommaIndex(json, start, commaIndex + 1); - } } return commaIndex; } - protected int getClosingIndex(String json, char openChar, char closeChar, int from) { - int nextOpenIndex = json.indexOf(openChar, from + 1); - int closingIndex = json.indexOf(closeChar, from + 1); + protected static int getClosingIndex(String json, char openChar, char closeChar, int from) { + int nextOpenIndex = getNextSepCharIndex(json, openChar, from + 1); + int closingIndex = getNextSepCharIndex(json, closeChar, from + 1); while (nextOpenIndex != -1 && nextOpenIndex < closingIndex) { - nextOpenIndex = json.indexOf(openChar, nextOpenIndex + 1); - closingIndex = json.indexOf(closeChar, closingIndex + 1); + nextOpenIndex = getNextSepCharIndex(json, openChar, nextOpenIndex + 1); + closingIndex = getNextSepCharIndex(json, closeChar, closingIndex + 1); } return closingIndex; } + protected static int getNextSepCharIndex(String json, char curlyBracketChar, int from) { + int nextCurlyBracketIndex = -1; + boolean inString = false; + for (int i = from; i < json.length(); i++) { + char currentChar = json.charAt(i); + if (currentChar == curlyBracketChar && !inString) { + nextCurlyBracketIndex = i; + break; + } else if (currentChar == DQUOTE) { + if (i > from && json.charAt(i - 1) == ESCAPE) { + continue; + } + inString = !inString; + } + } + return nextCurlyBracketIndex; + } + public void setFormat(boolean format) { this.format = format; } http://git-wip-us.apache.org/repos/asf/cxf/blob/8d485322/rt/rs/extensions/json-basic/src/test/java/org/apache/cxf/jaxrs/json/basic/JsonMapObjectReaderWriterTest.java ---------------------------------------------------------------------- diff --git a/rt/rs/extensions/json-basic/src/test/java/org/apache/cxf/jaxrs/json/basic/JsonMapObjectReaderWriterTest.java b/rt/rs/extensions/json-basic/src/test/java/org/apache/cxf/jaxrs/json/basic/JsonMapObjectReaderWriterTest.java index 1500354..874beeb 100644 --- a/rt/rs/extensions/json-basic/src/test/java/org/apache/cxf/jaxrs/json/basic/JsonMapObjectReaderWriterTest.java +++ b/rt/rs/extensions/json-basic/src/test/java/org/apache/cxf/jaxrs/json/basic/JsonMapObjectReaderWriterTest.java @@ -24,6 +24,8 @@ import java.util.Date; import java.util.LinkedHashMap; import java.util.Map; +import org.apache.cxf.helpers.CastUtils; + import org.junit.Assert; import org.junit.Test; @@ -68,4 +70,58 @@ public class JsonMapObjectReaderWriterTest extends Assert { assertEquals(Collections.singletonList("cValue1, cValue2"), map.get("c")); assertEquals("dValue1,dValue2,dValue3,dValue4", map.get("d")); } + @Test + public void testReadStringWithLeftCurlyBracketInString() throws Exception { + JsonMapObjectReaderWriter jsonMapObjectReaderWriter = new JsonMapObjectReaderWriter(); + String s = "{\"x\":{\"y\":\"{\"}}"; + Map<String, Object> map = jsonMapObjectReaderWriter.fromJson(s); + assertEquals(1, map.size()); + Map<String, Object> xMap = CastUtils.cast((Map<?, ?>)map.get("x")); + assertEquals(1, xMap.size()); + assertEquals("{", xMap.get("y")); + } + @Test + public void testReadStringWithLeftCurlyBracketInString2() throws Exception { + JsonMapObjectReaderWriter jsonMapObjectReaderWriter = new JsonMapObjectReaderWriter(); + String s = "{\"x\":{\"y\":\"{\", \"z\":\"{\"}, \"a\":\"b\"}"; + Map<String, Object> map = jsonMapObjectReaderWriter.fromJson(s); + assertEquals(2, map.size()); + assertEquals("b", map.get("a")); + Map<String, Object> xMap = CastUtils.cast((Map<?, ?>)map.get("x")); + assertEquals(2, xMap.size()); + assertEquals("{", xMap.get("y")); + assertEquals("{", xMap.get("z")); + } + @Test + public void testReadStringWithRightCurlyBracketInString() throws Exception { + JsonMapObjectReaderWriter jsonMapObjectReaderWriter = new JsonMapObjectReaderWriter(); + String s = "{\"x\":{\"y\":\"}\"}}"; + Map<String, Object> map = jsonMapObjectReaderWriter.fromJson(s); + assertEquals(1, map.size()); + Map<String, Object> xMap = CastUtils.cast((Map<?, ?>)map.get("x")); + assertEquals(1, xMap.size()); + assertEquals("}", xMap.get("y")); + } + @Test + public void testReadStringWithRightCurlyBracketInString2() throws Exception { + JsonMapObjectReaderWriter jsonMapObjectReaderWriter = new JsonMapObjectReaderWriter(); + String s = "{\"x\":{\"y\":\"}\", \"z\":\"}\"}, \"a\":\"b\"}"; + Map<String, Object> map = jsonMapObjectReaderWriter.fromJson(s); + assertEquals(2, map.size()); + assertEquals("b", map.get("a")); + Map<String, Object> xMap = CastUtils.cast((Map<?, ?>)map.get("x")); + assertEquals(2, xMap.size()); + assertEquals("}", xMap.get("y")); + assertEquals("}", xMap.get("z")); + } + @Test + public void testReadStringWithCurlyBracketsInString() throws Exception { + JsonMapObjectReaderWriter jsonMapObjectReaderWriter = new JsonMapObjectReaderWriter(); + String s = "{\"x\":{\"y\":\"{\\\"}\"}}"; + Map<String, Object> map = jsonMapObjectReaderWriter.fromJson(s); + assertEquals(1, map.size()); + Map<String, Object> xMap = CastUtils.cast((Map<?, ?>)map.get("x")); + assertEquals(1, xMap.size()); + assertEquals("{\\\"}", xMap.get("y")); + } }