Forráskód Böngészése

#133 validate json when Skip()

Tao Wen 8 éve
szülő
commit
f6da8e62c3

+ 1 - 2
feature_iter.go

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

+ 14 - 2
feature_iter_object.go

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

+ 2 - 2
feature_iter_skip.go

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

+ 10 - 0
feature_iter_skip_strict.go

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

+ 18 - 19
jsoniter_any_string_test.go

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

+ 0 - 5
jsoniter_io_test.go

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

+ 1 - 0
jsoniter_object_test.go

@@ -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 - 0
skip_tests/array/inputs.go

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

+ 1 - 0
skip_tests/array/skip_test.go

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

+ 5 - 5
skip_tests/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 - 0
skip_tests/object/inputs.go

@@ -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 - 0
skip_tests/object/skip_test.go

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

+ 7 - 7
skip_tests/string/inputs.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
 }

+ 0 - 2
unmarshal_input_test.go

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