diff --git a/src/main/java/com/alibaba/fastjson/parser/JSONLexerBase.java b/src/main/java/com/alibaba/fastjson/parser/JSONLexerBase.java index cf37d6182b..7c5d1ac2f4 100755 --- a/src/main/java/com/alibaba/fastjson/parser/JSONLexerBase.java +++ b/src/main/java/com/alibaba/fastjson/parser/JSONLexerBase.java @@ -1276,7 +1276,6 @@ public String scanString(char expectNextChar) { return stringDefaultValue(); } - boolean hasSpecial = false; final String strVal; { int startIndex = bp + 1; @@ -1308,12 +1307,6 @@ public String scanString(char expectNextChar) { stringVal = readString(chars, chars_len); } - if (hasSpecial) { - matchStat = NOT_MATCH; - - return stringDefaultValue(); - } - offset += (endIndex - (bp + 1) + 1); chLocal = charAt(bp + (offset++)); strVal = stringVal; @@ -1524,30 +1517,51 @@ public Collection scanFieldStringArray(char[] fieldName, Class type) chLocal = charAt(bp + (offset++)); for (;;) { - if (chLocal != '"') { - matchStat = NOT_MATCH; - return null; - } - - String strVal; // int start = index; - int startOffset = offset; - for (;;) { - chLocal = charAt(bp + (offset++)); - if (chLocal == '\"') { - int start = bp + startOffset; - int len = bp + offset - start - 1; - strVal = subString(start, len); - list.add(strVal); - - chLocal = charAt(bp + (offset++)); - break; + if (chLocal == '"') { + int startIndex = bp + offset; + int endIndex = indexOf('"', startIndex); + if (endIndex == -1) { + throw new JSONException("unclosed str"); } - if (chLocal == '\\') { - matchStat = NOT_MATCH; - return null; + int startIndex2 = bp + offset; // must re compute + String stringVal = subString(startIndex2, endIndex - startIndex2); + if (stringVal.indexOf('\\') != -1) { + for (;;) { + int slashCount = 0; + for (int i = endIndex - 1; i >= 0; --i) { + if (charAt(i) == '\\') { + slashCount++; + } else { + break; + } + } + if (slashCount % 2 == 0) { + break; + } + endIndex = indexOf('"', endIndex + 1); + } + + int chars_len = endIndex - (bp + offset); + char[] chars = sub_chars(bp + offset, chars_len); + + stringVal = readString(chars, chars_len); } + + offset += (endIndex - (bp + offset) + 1); + chLocal = charAt(bp + (offset++)); + + list.add(stringVal); + } else if (chLocal == 'n' && charAt(bp + offset) == 'u' && charAt(bp + offset + 1) == 'l' && charAt(bp + offset + 2) == 'l') { + offset += 3; + chLocal = charAt(bp + (offset++)); + list.add(null); + } else if (chLocal == ']' && list.size() == 0) { + chLocal = charAt(bp + (offset++)); + break; + } else { + throw new JSONException("illega str"); } if (chLocal == ',') { diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/list/ListStringFieldTest_stream.java b/src/test/java/com/alibaba/json/bvt/parser/deser/list/ListStringFieldTest_stream.java new file mode 100644 index 0000000000..936a97f0ea --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/list/ListStringFieldTest_stream.java @@ -0,0 +1,143 @@ +package com.alibaba.json.bvt.parser.deser.list; + +import java.io.StringReader; +import java.util.List; +import java.util.Map; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSONException; +import com.alibaba.fastjson.JSONReader; +import com.alibaba.fastjson.TypeReference; + +import junit.framework.TestCase; + +public class ListStringFieldTest_stream extends TestCase { + + public void test_list() throws Exception { + String text = "{\"values\":[\"a\",null,\"b\",\"ab\\\\c\"]}"; + + JSONReader reader = new JSONReader(new StringReader(text)); + Model model = reader.readObject(Model.class); + Assert.assertEquals(4, model.values.size()); + Assert.assertEquals("a", model.values.get(0)); + Assert.assertEquals(null, model.values.get(1)); + Assert.assertEquals("b", model.values.get(2)); + Assert.assertEquals("ab\\c", model.values.get(3)); + } + + public void test_null() throws Exception { + String text = "{\"values\":null}"; + JSONReader reader = new JSONReader(new StringReader(text)); + Model model = reader.readObject(Model.class); + Assert.assertNull(model.values); + } + + public void test_empty() throws Exception { + String text = "{\"values\":[]}"; + JSONReader reader = new JSONReader(new StringReader(text)); + Model model = reader.readObject(Model.class); + Assert.assertEquals(0, model.values.size()); + } + + public void test_map_empty() throws Exception { + String text = "{\"model\":{\"values\":[]}}"; + JSONReader reader = new JSONReader(new StringReader(text)); + Map map = reader.readObject(new TypeReference>() { + }); + Model model = (Model) map.get("model"); + Assert.assertEquals(0, model.values.size()); + } + + public void test_notMatch() throws Exception { + String text = "{\"value\":[]}"; + JSONReader reader = new JSONReader(new StringReader(text)); + Model model = reader.readObject(Model.class); + Assert.assertNull(model.values); + } + + public void test_error() throws Exception { + String text = "{\"values\":[1"; + JSONReader reader = new JSONReader(new StringReader(text)); + + Exception error = null; + try { + reader.readObject(Model.class); + } catch (JSONException ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public void test_error_1() throws Exception { + String text = "{\"values\":[\"b\"["; + JSONReader reader = new JSONReader(new StringReader(text)); + + Exception error = null; + try { + reader.readObject(Model.class); + } catch (JSONException ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public void test_error_2() throws Exception { + String text = "{\"model\":{\"values\":[]["; + JSONReader reader = new JSONReader(new StringReader(text)); + + + Exception error = null; + try { + reader.readObject(new TypeReference>() { + }); + } catch (JSONException ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public void test_error_3() throws Exception { + String text = "{\"model\":{\"values\":[]}["; + JSONReader reader = new JSONReader(new StringReader(text)); + + + Exception error = null; + try { + reader.readObject(new TypeReference>() { + }); + } catch (JSONException ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public void test_error_4() throws Exception { + String text = "{\"model\":{\"values\":[]}}"; + JSONReader reader = new JSONReader(new StringReader(text)); + + + Exception error = null; + try { + reader.readObject(new TypeReference>() { + }); + } catch (JSONException ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public static class Model { + + private List values; + + public List getValues() { + return values; + } + + public void setValues(List values) { + this.values = values; + } + + } +}