mirror of
https://github.com/json-iterator/go.git
synced 2025-05-16 21:45:43 +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() {
|
func (iter *Iterator) unreadByte() {
|
||||||
if iter.head == 0 {
|
if iter.Error != nil {
|
||||||
iter.ReportError("unreadByte", "unread too many bytes")
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
iter.head--
|
iter.head--
|
||||||
|
@ -88,11 +88,17 @@ func (iter *Iterator) ReadObjectCB(callback func(*Iterator, string) bool) bool {
|
|||||||
if !callback(iter, *(*string)(unsafe.Pointer(&field))) {
|
if !callback(iter, *(*string)(unsafe.Pointer(&field))) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
for iter.nextToken() == ',' {
|
c = iter.nextToken()
|
||||||
|
for c == ',' {
|
||||||
field = iter.readObjectFieldAsBytes()
|
field = iter.readObjectFieldAsBytes()
|
||||||
if !callback(iter, *(*string)(unsafe.Pointer(&field))) {
|
if !callback(iter, *(*string)(unsafe.Pointer(&field))) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
c = iter.nextToken()
|
||||||
|
}
|
||||||
|
if c != '}' {
|
||||||
|
iter.ReportError("ReadObjectCB", `object not ended with }`)
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@ -125,7 +131,8 @@ func (iter *Iterator) ReadMapCB(callback func(*Iterator, string) bool) bool {
|
|||||||
if !callback(iter, field) {
|
if !callback(iter, field) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
for iter.nextToken() == ',' {
|
c = iter.nextToken()
|
||||||
|
for c == ',' {
|
||||||
field = iter.ReadString()
|
field = iter.ReadString()
|
||||||
if iter.nextToken() != ':' {
|
if iter.nextToken() != ':' {
|
||||||
iter.ReportError("ReadMapCB", "expect : after object field")
|
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) {
|
if !callback(iter, field) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
c = iter.nextToken()
|
||||||
|
}
|
||||||
|
if c != '}' {
|
||||||
|
iter.ReportError("ReadMapCB", `object not ended with }`)
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -80,9 +80,9 @@ func (iter *Iterator) Skip() {
|
|||||||
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 '[':
|
||||||
panic("not implemented")
|
iter.skipArray()
|
||||||
case '{':
|
case '{':
|
||||||
panic("not implemented")
|
iter.skipObject()
|
||||||
default:
|
default:
|
||||||
iter.ReportError("Skip", fmt.Sprintf("do not know how to skip: %v", c))
|
iter.ReportError("Skip", fmt.Sprintf("do not know how to skip: %v", c))
|
||||||
return
|
return
|
||||||
|
@ -61,7 +61,17 @@ func (iter *Iterator) trySkipString() bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (iter *Iterator) skipObject() {
|
func (iter *Iterator) skipObject() {
|
||||||
|
iter.unreadByte()
|
||||||
|
iter.ReadObjectCB(func(iter *Iterator, field string) bool {
|
||||||
|
iter.Skip()
|
||||||
|
return true
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (iter *Iterator) skipArray() {
|
func (iter *Iterator) skipArray() {
|
||||||
|
iter.unreadByte()
|
||||||
|
iter.ReadArrayCB(func(iter *Iterator) bool {
|
||||||
|
iter.Skip()
|
||||||
|
return true
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,6 @@ var stringConvertMap = map[string]string{
|
|||||||
"[]": "[]",
|
"[]": "[]",
|
||||||
"[1,2]": "[1,2]",
|
"[1,2]": "[1,2]",
|
||||||
"{}": "{}",
|
"{}": "{}",
|
||||||
"{1,2}": "{1,2}",
|
|
||||||
`{"a":1, "stream":true}`: `{"a":1, "stream":true}`,
|
`{"a":1, "stream":true}`: `{"a":1, "stream":true}`,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,11 +20,6 @@ func Test_read_by_one(t *testing.T) {
|
|||||||
if iter.Error != nil {
|
if iter.Error != nil {
|
||||||
t.Fatal(iter.Error)
|
t.Fatal(iter.Error)
|
||||||
}
|
}
|
||||||
iter.unreadByte()
|
|
||||||
if iter.Error == nil {
|
|
||||||
t.FailNow()
|
|
||||||
}
|
|
||||||
iter.Error = nil
|
|
||||||
b = iter.readByte()
|
b = iter.readByte()
|
||||||
if iter.Error != nil {
|
if iter.Error != nil {
|
||||||
t.Fatal(iter.Error)
|
t.Fatal(iter.Error)
|
||||||
|
@ -32,6 +32,7 @@ func Test_one_field(t *testing.T) {
|
|||||||
iter = ParseString(ConfigDefault, `{"a": "stream"}`)
|
iter = ParseString(ConfigDefault, `{"a": "stream"}`)
|
||||||
should.True(iter.ReadObjectCB(func(iter *Iterator, field string) bool {
|
should.True(iter.ReadObjectCB(func(iter *Iterator, field string) bool {
|
||||||
should.Equal("a", field)
|
should.Equal("a", field)
|
||||||
|
iter.Skip()
|
||||||
return true
|
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 (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"github.com/json-iterator/go"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
"io"
|
"io"
|
||||||
"testing"
|
"testing"
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
"github.com/json-iterator/go"
|
|
||||||
"errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func Test_skip(t *testing.T) {
|
func Test_skip(t *testing.T) {
|
||||||
for _, input := range inputs {
|
for _, input := range inputs {
|
||||||
t.Run(input, func(t *testing.T) {
|
t.Run(input, func(t *testing.T) {
|
||||||
should := require.New(t)
|
should := require.New(t)
|
||||||
dst := typeForTest(0)
|
var dst typeForTest
|
||||||
stdErr := json.Unmarshal([]byte(input), &dst)
|
stdErr := json.Unmarshal([]byte(input), &dst)
|
||||||
iter := jsoniter.ParseString(jsoniter.ConfigDefault, input)
|
iter := jsoniter.ParseString(jsoniter.ConfigDefault, input)
|
||||||
iter.Skip()
|
iter.Skip()
|
||||||
|
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
|
@ -27,7 +27,6 @@ func Test_EmptyInput(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func Test_RandomInput_Bytes(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)
|
fz := fuzz.New().NilChance(0)
|
||||||
for i := 0; i < 10000; i++ {
|
for i := 0; i < 10000; i++ {
|
||||||
var jb []byte
|
var jb []byte
|
||||||
@ -37,7 +36,6 @@ func Test_RandomInput_Bytes(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func Test_RandomInput_String(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)
|
fz := fuzz.New().NilChance(0)
|
||||||
for i := 0; i < 10000; i++ {
|
for i := 0; i < 10000; i++ {
|
||||||
var js string
|
var js string
|
||||||
|
Loading…
x
Reference in New Issue
Block a user