Skip to content

Commit

Permalink
Merge pull request #91 from francoispqt/fix/skip-unicode-string
Browse files Browse the repository at this point in the history
Fix error when skipping string with unicode
  • Loading branch information
francoispqt committed Dec 5, 2018
2 parents ef10bf3 + 41189cb commit 73600a9
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 8 deletions.
46 changes: 44 additions & 2 deletions decode_object_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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!",
Expand All @@ -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 {
Expand Down
11 changes: 9 additions & 2 deletions decode_string.go
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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()
Expand Down
12 changes: 8 additions & 4 deletions decode_string_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -738,20 +738,24 @@ 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 {
assert.NotNil(t, err, "err should not be nil")
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")
}
}

0 comments on commit 73600a9

Please sign in to comment.