You've already forked json-iterator
mirror of
https://github.com/json-iterator/go.git
synced 2025-06-27 23:18:42 +02:00
Merge branch 'liggitt-malformed-string-test'
This commit is contained in:
@ -143,13 +143,13 @@ func (iter *Iterator) readAny() Any {
|
|||||||
iter.unreadByte()
|
iter.unreadByte()
|
||||||
return &stringAny{baseAny{}, iter.ReadString()}
|
return &stringAny{baseAny{}, iter.ReadString()}
|
||||||
case 'n':
|
case 'n':
|
||||||
iter.skipFixedBytes(3) // null
|
iter.skipThreeBytes('u', 'l', 'l') // null
|
||||||
return &nilAny{}
|
return &nilAny{}
|
||||||
case 't':
|
case 't':
|
||||||
iter.skipFixedBytes(3) // true
|
iter.skipThreeBytes('r', 'u', 'e') // true
|
||||||
return &trueAny{}
|
return &trueAny{}
|
||||||
case 'f':
|
case 'f':
|
||||||
iter.skipFixedBytes(4) // false
|
iter.skipFourBytes('a', 'l', 's', 'e') // false
|
||||||
return &falseAny{}
|
return &falseAny{}
|
||||||
case '{':
|
case '{':
|
||||||
return iter.readObjectAny()
|
return iter.readObjectAny()
|
||||||
|
@ -275,7 +275,7 @@ func (iter *Iterator) Read() interface{} {
|
|||||||
case Number:
|
case Number:
|
||||||
return iter.ReadFloat64()
|
return iter.ReadFloat64()
|
||||||
case Nil:
|
case Nil:
|
||||||
iter.skipFixedBytes(4) // null
|
iter.skipFourBytes('n', 'u', 'l', 'l')
|
||||||
return nil
|
return nil
|
||||||
case Bool:
|
case Bool:
|
||||||
return iter.ReadBool()
|
return iter.ReadBool()
|
||||||
|
@ -5,7 +5,7 @@ func (iter *Iterator) ReadArray() (ret bool) {
|
|||||||
c := iter.nextToken()
|
c := iter.nextToken()
|
||||||
switch c {
|
switch c {
|
||||||
case 'n':
|
case 'n':
|
||||||
iter.skipFixedBytes(3)
|
iter.skipThreeBytes('u', 'l', 'l')
|
||||||
return false // null
|
return false // null
|
||||||
case '[':
|
case '[':
|
||||||
c = iter.nextToken()
|
c = iter.nextToken()
|
||||||
@ -44,7 +44,7 @@ func (iter *Iterator) ReadArrayCB(callback func(*Iterator) bool) (ret bool) {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if c == 'n' {
|
if c == 'n' {
|
||||||
iter.skipFixedBytes(3)
|
iter.skipThreeBytes('u', 'l', 'l')
|
||||||
return true // null
|
return true // null
|
||||||
}
|
}
|
||||||
iter.ReportError("ReadArrayCB", "expect [ or n, but found: "+string([]byte{c}))
|
iter.ReportError("ReadArrayCB", "expect [ or n, but found: "+string([]byte{c}))
|
||||||
|
@ -13,7 +13,7 @@ func (iter *Iterator) ReadObject() (ret string) {
|
|||||||
c := iter.nextToken()
|
c := iter.nextToken()
|
||||||
switch c {
|
switch c {
|
||||||
case 'n':
|
case 'n':
|
||||||
iter.skipFixedBytes(3)
|
iter.skipThreeBytes('u', 'l', 'l')
|
||||||
return "" // null
|
return "" // null
|
||||||
case '{':
|
case '{':
|
||||||
c = iter.nextToken()
|
c = iter.nextToken()
|
||||||
@ -103,7 +103,7 @@ func (iter *Iterator) ReadObjectCB(callback func(*Iterator, string) bool) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if c == 'n' {
|
if c == 'n' {
|
||||||
iter.skipFixedBytes(3)
|
iter.skipThreeBytes('u', 'l', 'l')
|
||||||
return true // null
|
return true // null
|
||||||
}
|
}
|
||||||
iter.ReportError("ReadObjectCB", `expect { or n`)
|
iter.ReportError("ReadObjectCB", `expect { or n`)
|
||||||
@ -144,7 +144,7 @@ func (iter *Iterator) ReadMapCB(callback func(*Iterator, string) bool) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if c == 'n' {
|
if c == 'n' {
|
||||||
iter.skipFixedBytes(3)
|
iter.skipThreeBytes('u', 'l', 'l')
|
||||||
return true // null
|
return true // null
|
||||||
}
|
}
|
||||||
iter.ReportError("ReadMapCB", `expect { or n`)
|
iter.ReportError("ReadMapCB", `expect { or n`)
|
||||||
@ -161,7 +161,7 @@ func (iter *Iterator) readObjectStart() bool {
|
|||||||
iter.unreadByte()
|
iter.unreadByte()
|
||||||
return true
|
return true
|
||||||
} else if c == 'n' {
|
} else if c == 'n' {
|
||||||
iter.skipFixedBytes(3)
|
iter.skipThreeBytes('u', 'l', 'l')
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
iter.ReportError("readObjectStart", "expect { or n")
|
iter.ReportError("readObjectStart", "expect { or n")
|
||||||
|
@ -7,7 +7,7 @@ import "fmt"
|
|||||||
func (iter *Iterator) ReadNil() (ret bool) {
|
func (iter *Iterator) ReadNil() (ret bool) {
|
||||||
c := iter.nextToken()
|
c := iter.nextToken()
|
||||||
if c == 'n' {
|
if c == 'n' {
|
||||||
iter.skipFixedBytes(3) // null
|
iter.skipThreeBytes('u', 'l', 'l') // null
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
iter.unreadByte()
|
iter.unreadByte()
|
||||||
@ -18,11 +18,11 @@ func (iter *Iterator) ReadNil() (ret bool) {
|
|||||||
func (iter *Iterator) ReadBool() (ret bool) {
|
func (iter *Iterator) ReadBool() (ret bool) {
|
||||||
c := iter.nextToken()
|
c := iter.nextToken()
|
||||||
if c == 't' {
|
if c == 't' {
|
||||||
iter.skipFixedBytes(3)
|
iter.skipThreeBytes('r', 'u', 'e')
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if c == 'f' {
|
if c == 'f' {
|
||||||
iter.skipFixedBytes(4)
|
iter.skipFourBytes('a', 'l', 's', 'e')
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
iter.ReportError("ReadBool", "expect t or f")
|
iter.ReportError("ReadBool", "expect t or f")
|
||||||
@ -71,10 +71,12 @@ func (iter *Iterator) Skip() {
|
|||||||
switch c {
|
switch c {
|
||||||
case '"':
|
case '"':
|
||||||
iter.skipString()
|
iter.skipString()
|
||||||
case 'n', 't':
|
case 'n':
|
||||||
iter.skipFixedBytes(3) // null or true
|
iter.skipThreeBytes('u', 'l', 'l') // null
|
||||||
|
case 't':
|
||||||
|
iter.skipThreeBytes('r', 'u', 'e') // true
|
||||||
case 'f':
|
case 'f':
|
||||||
iter.skipFixedBytes(4) // false
|
iter.skipFourBytes('a', 'l', 's', 'e') // false
|
||||||
case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
|
case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
|
||||||
iter.skipNumber()
|
iter.skipNumber()
|
||||||
case '[':
|
case '[':
|
||||||
@ -226,16 +228,36 @@ func (iter *Iterator) skipNumber() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (iter *Iterator) skipFixedBytes(n int) {
|
func (iter *Iterator) skipFourBytes(b1, b2, b3, b4 byte) {
|
||||||
iter.head += n
|
if iter.readByte() != b1 {
|
||||||
if iter.head >= iter.tail {
|
iter.ReportError("skipFourBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3, b4})))
|
||||||
more := iter.head - iter.tail
|
return
|
||||||
if !iter.loadMore() {
|
}
|
||||||
if more > 0 {
|
if iter.readByte() != b2 {
|
||||||
iter.ReportError("skipFixedBytes", "unexpected end")
|
iter.ReportError("skipFourBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3, b4})))
|
||||||
}
|
return
|
||||||
return
|
}
|
||||||
}
|
if iter.readByte() != b3 {
|
||||||
iter.head += more
|
iter.ReportError("skipFourBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3, b4})))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if iter.readByte() != b4 {
|
||||||
|
iter.ReportError("skipFourBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3, b4})))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (iter *Iterator) skipThreeBytes(b1, b2, b3 byte) {
|
||||||
|
if iter.readByte() != b1 {
|
||||||
|
iter.ReportError("skipThreeBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3})))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if iter.readByte() != b2 {
|
||||||
|
iter.ReportError("skipThreeBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3})))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if iter.readByte() != b3 {
|
||||||
|
iter.ReportError("skipThreeBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3})))
|
||||||
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ package jsoniter
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"unicode/utf16"
|
"unicode/utf16"
|
||||||
|
"fmt"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ReadString read string from iterator
|
// ReadString read string from iterator
|
||||||
@ -16,11 +17,15 @@ func (iter *Iterator) ReadString() (ret string) {
|
|||||||
return ret
|
return ret
|
||||||
} else if c == '\\' {
|
} else if c == '\\' {
|
||||||
break
|
break
|
||||||
|
} else if c < ' ' {
|
||||||
|
iter.ReportError("ReadString",
|
||||||
|
fmt.Sprintf(`invalid control character found: %d`, c))
|
||||||
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return iter.readStringSlowPath()
|
return iter.readStringSlowPath()
|
||||||
} else if c == 'n' {
|
} else if c == 'n' {
|
||||||
iter.skipFixedBytes(3)
|
iter.skipThreeBytes('u', 'l', 'l')
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
iter.ReportError("ReadString", `expects " or n`)
|
iter.ReportError("ReadString", `expects " or n`)
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"testing"
|
"testing"
|
||||||
|
"io"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Test_read_null(t *testing.T) {
|
func Test_read_null(t *testing.T) {
|
||||||
@ -13,6 +14,12 @@ func Test_read_null(t *testing.T) {
|
|||||||
should.True(iter.ReadNil())
|
should.True(iter.ReadNil())
|
||||||
iter = ParseString(ConfigDefault, `null`)
|
iter = ParseString(ConfigDefault, `null`)
|
||||||
should.Nil(iter.Read())
|
should.Nil(iter.Read())
|
||||||
|
iter = ParseString(ConfigDefault, `navy`)
|
||||||
|
iter.Read()
|
||||||
|
should.True(iter.Error != nil && iter.Error != io.EOF)
|
||||||
|
iter = ParseString(ConfigDefault, `navy`)
|
||||||
|
iter.ReadNil()
|
||||||
|
should.True(iter.Error != nil && iter.Error != io.EOF)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Test_write_null(t *testing.T) {
|
func Test_write_null(t *testing.T) {
|
||||||
|
@ -6,11 +6,61 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
"testing"
|
"testing"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func Test_read_string(t *testing.T) {
|
||||||
|
badInputs := []string{
|
||||||
|
``,
|
||||||
|
`"`,
|
||||||
|
`"\"`,
|
||||||
|
`"\\\"`,
|
||||||
|
"\"\n\"",
|
||||||
|
}
|
||||||
|
for i :=0; i < 32; i++ {
|
||||||
|
// control characters are invalid
|
||||||
|
badInputs = append(badInputs, string([]byte{'"', byte(i), '"'}))
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, input := range badInputs {
|
||||||
|
testReadString(t, input, "", true, "json.Unmarshal", json.Unmarshal)
|
||||||
|
testReadString(t, input, "", true, "jsoniter.Unmarshal", Unmarshal)
|
||||||
|
testReadString(t, input, "", true, "jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal", ConfigCompatibleWithStandardLibrary.Unmarshal)
|
||||||
|
}
|
||||||
|
|
||||||
|
goodInputs := []struct {
|
||||||
|
input string
|
||||||
|
expectValue string
|
||||||
|
}{
|
||||||
|
{`""`, ""},
|
||||||
|
{`"a"`, "a"},
|
||||||
|
{`null`, ""},
|
||||||
|
{`"Iñtërnâtiônàlizætiøn,💝🐹🌇⛔"`, "Iñtërnâtiônàlizætiøn,💝🐹🌇⛔"},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range goodInputs {
|
||||||
|
testReadString(t, tc.input, tc.expectValue, false, "json.Unmarshal", json.Unmarshal)
|
||||||
|
testReadString(t, tc.input, tc.expectValue, false, "jsoniter.Unmarshal", Unmarshal)
|
||||||
|
testReadString(t, tc.input, tc.expectValue, false, "jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal", ConfigCompatibleWithStandardLibrary.Unmarshal)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func testReadString(t *testing.T, input string, expectValue string, expectError bool, marshalerName string, marshaler func([]byte, interface{}) error) {
|
||||||
|
var value string
|
||||||
|
err := marshaler([]byte(input), &value)
|
||||||
|
if expectError != (err != nil) {
|
||||||
|
t.Errorf("%q: %s: expected error %v, got %v", input, marshalerName, expectError, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if value != expectValue {
|
||||||
|
t.Errorf("%q: %s: expected %q, got %q", input, marshalerName, expectValue, value)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func Test_read_normal_string(t *testing.T) {
|
func Test_read_normal_string(t *testing.T) {
|
||||||
cases := map[string]string{
|
cases := map[string]string{
|
||||||
`"0123456789012345678901234567890123456789"`: `0123456789012345678901234567890123456789`,
|
`"0123456789012345678901234567890123456789"`: `0123456789012345678901234567890123456789`,
|
||||||
|
Reference in New Issue
Block a user