1
0
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:
Tao Wen 2017-07-18 09:45:25 +08:00
parent 5eded4f6ae
commit f6da8e62c3
14 changed files with 88 additions and 44 deletions

View File

@ -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--

View File

@ -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
}

View File

@ -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

View File

@ -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
})
}

View File

@ -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}`,
}

View File

@ -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)

View File

@ -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
}))

View File

@ -0,0 +1,12 @@
package test
type typeForTest []interface{}
var inputs = []string{
`[]`, // valid
`[1]`, // valid
`[ 1, "hello"]`, // valid
`[abc]`, // invalid
`[`, // invalid
`[[]`, // invalid
}

View File

@ -0,0 +1 @@
../number/skip_test.go

View File

@ -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) {
}
})
}
}
}

View 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
}

View File

@ -0,0 +1 @@
../number/skip_test.go

View File

@ -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
}

View File

@ -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