mirror of
https://github.com/json-iterator/go.git
synced 2024-11-24 08:22:14 +02:00
#133 validate json when Skip()
This commit is contained in:
parent
5eded4f6ae
commit
f6da8e62c3
@ -259,8 +259,7 @@ func (iter *Iterator) loadMore() bool {
|
||||
}
|
||||
|
||||
func (iter *Iterator) unreadByte() {
|
||||
if iter.head == 0 {
|
||||
iter.ReportError("unreadByte", "unread too many bytes")
|
||||
if iter.Error != nil {
|
||||
return
|
||||
}
|
||||
iter.head--
|
||||
|
@ -88,11 +88,17 @@ func (iter *Iterator) ReadObjectCB(callback func(*Iterator, string) bool) bool {
|
||||
if !callback(iter, *(*string)(unsafe.Pointer(&field))) {
|
||||
return false
|
||||
}
|
||||
for iter.nextToken() == ',' {
|
||||
c = iter.nextToken()
|
||||
for c == ',' {
|
||||
field = iter.readObjectFieldAsBytes()
|
||||
if !callback(iter, *(*string)(unsafe.Pointer(&field))) {
|
||||
return false
|
||||
}
|
||||
c = iter.nextToken()
|
||||
}
|
||||
if c != '}' {
|
||||
iter.ReportError("ReadObjectCB", `object not ended with }`)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
@ -125,7 +131,8 @@ func (iter *Iterator) ReadMapCB(callback func(*Iterator, string) bool) bool {
|
||||
if !callback(iter, field) {
|
||||
return false
|
||||
}
|
||||
for iter.nextToken() == ',' {
|
||||
c = iter.nextToken()
|
||||
for c == ',' {
|
||||
field = iter.ReadString()
|
||||
if iter.nextToken() != ':' {
|
||||
iter.ReportError("ReadMapCB", "expect : after object field")
|
||||
@ -134,6 +141,11 @@ func (iter *Iterator) ReadMapCB(callback func(*Iterator, string) bool) bool {
|
||||
if !callback(iter, field) {
|
||||
return false
|
||||
}
|
||||
c = iter.nextToken()
|
||||
}
|
||||
if c != '}' {
|
||||
iter.ReportError("ReadMapCB", `object not ended with }`)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
@ -80,9 +80,9 @@ func (iter *Iterator) Skip() {
|
||||
case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
|
||||
iter.skipNumber()
|
||||
case '[':
|
||||
panic("not implemented")
|
||||
iter.skipArray()
|
||||
case '{':
|
||||
panic("not implemented")
|
||||
iter.skipObject()
|
||||
default:
|
||||
iter.ReportError("Skip", fmt.Sprintf("do not know how to skip: %v", c))
|
||||
return
|
||||
|
@ -61,7 +61,17 @@ func (iter *Iterator) trySkipString() bool {
|
||||
}
|
||||
|
||||
func (iter *Iterator) skipObject() {
|
||||
iter.unreadByte()
|
||||
iter.ReadObjectCB(func(iter *Iterator, field string) bool {
|
||||
iter.Skip()
|
||||
return true
|
||||
})
|
||||
}
|
||||
|
||||
func (iter *Iterator) skipArray() {
|
||||
iter.unreadByte()
|
||||
iter.ReadArrayCB(func(iter *Iterator) bool {
|
||||
iter.Skip()
|
||||
return true
|
||||
})
|
||||
}
|
||||
|
@ -7,25 +7,24 @@ import (
|
||||
)
|
||||
|
||||
var stringConvertMap = map[string]string{
|
||||
"null": "",
|
||||
"321.1": "321.1",
|
||||
`"1.1"`: "1.1",
|
||||
`"-123.1"`: "-123.1",
|
||||
"0.0": "0.0",
|
||||
"0": "0",
|
||||
`"0"`: "0",
|
||||
`"0.0"`: "0.0",
|
||||
`"00.0"`: "00.0",
|
||||
"true": "true",
|
||||
"false": "false",
|
||||
`"true"`: "true",
|
||||
`"false"`: "false",
|
||||
`"true123"`: "true123",
|
||||
`"+1"`: "+1",
|
||||
"[]": "[]",
|
||||
"[1,2]": "[1,2]",
|
||||
"{}": "{}",
|
||||
"{1,2}": "{1,2}",
|
||||
"null": "",
|
||||
"321.1": "321.1",
|
||||
`"1.1"`: "1.1",
|
||||
`"-123.1"`: "-123.1",
|
||||
"0.0": "0.0",
|
||||
"0": "0",
|
||||
`"0"`: "0",
|
||||
`"0.0"`: "0.0",
|
||||
`"00.0"`: "00.0",
|
||||
"true": "true",
|
||||
"false": "false",
|
||||
`"true"`: "true",
|
||||
`"false"`: "false",
|
||||
`"true123"`: "true123",
|
||||
`"+1"`: "+1",
|
||||
"[]": "[]",
|
||||
"[1,2]": "[1,2]",
|
||||
"{}": "{}",
|
||||
`{"a":1, "stream":true}`: `{"a":1, "stream":true}`,
|
||||
}
|
||||
|
||||
|
@ -20,11 +20,6 @@ func Test_read_by_one(t *testing.T) {
|
||||
if iter.Error != nil {
|
||||
t.Fatal(iter.Error)
|
||||
}
|
||||
iter.unreadByte()
|
||||
if iter.Error == nil {
|
||||
t.FailNow()
|
||||
}
|
||||
iter.Error = nil
|
||||
b = iter.readByte()
|
||||
if iter.Error != nil {
|
||||
t.Fatal(iter.Error)
|
||||
|
@ -32,6 +32,7 @@ func Test_one_field(t *testing.T) {
|
||||
iter = ParseString(ConfigDefault, `{"a": "stream"}`)
|
||||
should.True(iter.ReadObjectCB(func(iter *Iterator, field string) bool {
|
||||
should.Equal("a", field)
|
||||
iter.Skip()
|
||||
return true
|
||||
}))
|
||||
|
||||
|
12
skip_tests/array/inputs.go
Normal file
12
skip_tests/array/inputs.go
Normal file
@ -0,0 +1,12 @@
|
||||
package test
|
||||
|
||||
type typeForTest []interface{}
|
||||
|
||||
var inputs = []string{
|
||||
`[]`, // valid
|
||||
`[1]`, // valid
|
||||
`[ 1, "hello"]`, // valid
|
||||
`[abc]`, // invalid
|
||||
`[`, // invalid
|
||||
`[[]`, // invalid
|
||||
}
|
1
skip_tests/array/skip_test.go
Symbolic link
1
skip_tests/array/skip_test.go
Symbolic link
@ -0,0 +1 @@
|
||||
../number/skip_test.go
|
@ -2,18 +2,18 @@ package test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"github.com/json-iterator/go"
|
||||
"github.com/stretchr/testify/require"
|
||||
"io"
|
||||
"testing"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/json-iterator/go"
|
||||
"errors"
|
||||
)
|
||||
|
||||
func Test_skip(t *testing.T) {
|
||||
for _, input := range inputs {
|
||||
t.Run(input, func(t *testing.T) {
|
||||
should := require.New(t)
|
||||
dst := typeForTest(0)
|
||||
var dst typeForTest
|
||||
stdErr := json.Unmarshal([]byte(input), &dst)
|
||||
iter := jsoniter.ParseString(jsoniter.ConfigDefault, input)
|
||||
iter.Skip()
|
||||
@ -31,4 +31,4 @@ func Test_skip(t *testing.T) {
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
16
skip_tests/object/inputs.go
Normal file
16
skip_tests/object/inputs.go
Normal file
@ -0,0 +1,16 @@
|
||||
package test
|
||||
|
||||
type typeForTest struct{}
|
||||
|
||||
var inputs = []string{
|
||||
`{}`, // valid
|
||||
`{"hello":"world"}`, // valid
|
||||
`{hello:"world"}`, // invalid
|
||||
`{"hello:"world"}`, // invalid
|
||||
`{"hello","world"}`, // invalid
|
||||
`{"hello":{}`, // invalid
|
||||
`{"hello":{}}`, // valid
|
||||
`{"hello":{}}}`, // invalid
|
||||
`{"hello": { "hello": 1}}`, // valid
|
||||
`{abc}`, // invalid
|
||||
}
|
1
skip_tests/object/skip_test.go
Symbolic link
1
skip_tests/object/skip_test.go
Symbolic link
@ -0,0 +1 @@
|
||||
../number/skip_test.go
|
@ -3,12 +3,12 @@ package test
|
||||
type typeForTest string
|
||||
|
||||
var inputs = []string{
|
||||
`""`, // valid
|
||||
`"hello"`, // valid
|
||||
`"`, // invalid
|
||||
`"\"`, // invalid
|
||||
`"\x00"`, // invalid
|
||||
`""`, // valid
|
||||
`"hello"`, // valid
|
||||
`"`, // invalid
|
||||
`"\"`, // invalid
|
||||
`"\x00"`, // invalid
|
||||
"\"\x00\"", // invalid
|
||||
"\"\t\"", // invalid
|
||||
`"\t"`, // valid
|
||||
"\"\t\"", // invalid
|
||||
`"\t"`, // valid
|
||||
}
|
||||
|
@ -27,7 +27,6 @@ func Test_EmptyInput(t *testing.T) {
|
||||
}
|
||||
|
||||
func Test_RandomInput_Bytes(t *testing.T) {
|
||||
t.Skip("will need to write a safe version of Skip()")
|
||||
fz := fuzz.New().NilChance(0)
|
||||
for i := 0; i < 10000; i++ {
|
||||
var jb []byte
|
||||
@ -37,7 +36,6 @@ func Test_RandomInput_Bytes(t *testing.T) {
|
||||
}
|
||||
|
||||
func Test_RandomInput_String(t *testing.T) {
|
||||
t.Skip("will need to write a safe version of Skip()")
|
||||
fz := fuzz.New().NilChance(0)
|
||||
for i := 0; i < 10000; i++ {
|
||||
var js string
|
||||
|
Loading…
Reference in New Issue
Block a user