commit 73600a98c556ff2da24a90f556188b676eaaff31
parent ef10bf36a252f8bda1248cedda106996f6512379
Author: Francois Parquet <francois.parquet@gmail.com>
Date: Wed, 5 Dec 2018 12:08:09 +0800
Merge pull request #91 from francoispqt/fix/skip-unicode-string
Fix error when skipping string with unicode
Diffstat:
3 files changed, 61 insertions(+), 8 deletions(-)
diff --git a/decode_object_test.go b/decode_object_test.go
@@ -447,7 +447,7 @@ func TestDecodeObjectBasic(t *testing.T) {
err: false,
},
{
- name: "basic-skip-data",
+ name: "basic-skip-data-error-uint8-negative",
json: `{
"testStr": "hello world!",
"testInt": 4535,
@@ -469,7 +469,7 @@ func TestDecodeObjectBasic(t *testing.T) {
"testUint32": 343443,
"testUint64": 545665757,
"skipString": "skipping string with escaped \\n new line",
- "skipInt": 3,
+ "skipInt": 3
}`,
expectedResult: testObject{
testStr: "hello world!",
@@ -488,6 +488,48 @@ func TestDecodeObjectBasic(t *testing.T) {
},
err: true,
},
+ {
+ name: "skip-data-with-unicode",
+ json: `{
+ "skipString": "hello\u1234\u2123",
+ "testStr": "hello world!",
+ "testInt": 4535,
+ "testBool": true,
+ "testFloat32": 2.345,
+ "testFloat64": 123.677,
+ "testInt8": 23,
+ "skipObject": {
+ "escapedString": "string with unicode \u1234\u1234\u1234"
+ },
+ "testInt16": 1245,
+ "testInt32": 456778,
+ "testInt64": 1446685358,
+ "testUint8": 255,
+ "skipArray": [[],[],{}],
+ "testUint16": 3455,
+ "skipBool": true,
+ "skipNull": null,
+ "testUint32": 343443,
+ "testUint64": 545665757,
+ "skipInt": 3
+ }`,
+ expectedResult: testObject{
+ testStr: "hello world!",
+ testInt: 4535,
+ testBool: true,
+ testFloat32: 2.345,
+ testFloat64: 123.677,
+ testInt8: 23,
+ testInt16: 1245,
+ testInt32: 456778,
+ testInt64: 1446685358,
+ testUint8: 255,
+ testUint16: 3455,
+ testUint32: 343443,
+ testUint64: 545665757,
+ },
+ err: false,
+ },
}
for _, testCase := range testCases {
diff --git a/decode_string.go b/decode_string.go
@@ -178,6 +178,12 @@ func (dec *Decoder) skipEscapedString() error {
return dec.raiseInvalidJSONErr(dec.cursor)
}
return nil
+ case 'u': // is unicode, we skip the following characters and place the cursor one one byte backward to avoid it breaking when returning to skipString
+ if err := dec.skipString(); err != nil {
+ return err
+ }
+ dec.cursor--
+ return nil
case 'n', 'r', 't', '/', 'f', 'b':
return nil
default:
@@ -195,11 +201,12 @@ func (dec *Decoder) skipEscapedString() error {
func (dec *Decoder) skipString() error {
for dec.cursor < dec.length || dec.read() {
switch dec.data[dec.cursor] {
- // string found
+ // found the closing quote
+ // let's return
case '"':
dec.cursor = dec.cursor + 1
return nil
- // slash found
+ // solidus found start parsing an escaped string
case '\\':
dec.cursor = dec.cursor + 1
err := dec.skipEscapedString()
diff --git a/decode_string_test.go b/decode_string_test.go
@@ -738,10 +738,15 @@ func TestSkipString(t *testing.T) {
expectedResult: "",
err: false,
},
+ {
+ name: "string-unicode",
+ json: `[2]\u66fe\u5b97\u5357"`,
+ expectedResult: "",
+ err: false,
+ },
}
for _, testCase := range testCases {
- str := ""
dec := NewDecoder(strings.NewReader(testCase.json))
err := dec.skipString()
if testCase.err {
@@ -749,9 +754,8 @@ func TestSkipString(t *testing.T) {
if testCase.errType != nil {
assert.IsType(t, testCase.errType, err, "err should be of expected type")
}
- } else {
- assert.Nil(t, err, "err should be nil")
+ return
}
- assert.Equal(t, testCase.expectedResult, str, fmt.Sprintf("str should be equal to '%s'", testCase.expectedResult))
+ assert.Nil(t, err, "err should be nil")
}
}