summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--compat/json/testdata/fuzz/FuzzUnmarshalJSON/12cc404310c36cfd14cc33eac5eb4303f0d9d31e9c29a6892bb474a64e78fe5f2
-rw-r--r--compat/json/testdata/fuzz/FuzzUnmarshalJSON/df26c4ef7bfba3827830052ec4ae29b24d5dd803ffcfeff314198aef23e762572
-rw-r--r--decode.go3
-rw-r--r--decode_scan_test.go7
-rw-r--r--parse.go12
5 files changed, 24 insertions, 2 deletions
diff --git a/compat/json/testdata/fuzz/FuzzUnmarshalJSON/12cc404310c36cfd14cc33eac5eb4303f0d9d31e9c29a6892bb474a64e78fe5f b/compat/json/testdata/fuzz/FuzzUnmarshalJSON/12cc404310c36cfd14cc33eac5eb4303f0d9d31e9c29a6892bb474a64e78fe5f
new file mode 100644
index 0000000..8200529
--- /dev/null
+++ b/compat/json/testdata/fuzz/FuzzUnmarshalJSON/12cc404310c36cfd14cc33eac5eb4303f0d9d31e9c29a6892bb474a64e78fe5f
@@ -0,0 +1,2 @@
+go test fuzz v1
+[]byte("1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")
diff --git a/compat/json/testdata/fuzz/FuzzUnmarshalJSON/df26c4ef7bfba3827830052ec4ae29b24d5dd803ffcfeff314198aef23e76257 b/compat/json/testdata/fuzz/FuzzUnmarshalJSON/df26c4ef7bfba3827830052ec4ae29b24d5dd803ffcfeff314198aef23e76257
new file mode 100644
index 0000000..200e1a6
--- /dev/null
+++ b/compat/json/testdata/fuzz/FuzzUnmarshalJSON/df26c4ef7bfba3827830052ec4ae29b24d5dd803ffcfeff314198aef23e76257
@@ -0,0 +1,2 @@
+go test fuzz v1
+[]byte("[[0,]")
diff --git a/decode.go b/decode.go
index f630541..e42c115 100644
--- a/decode.go
+++ b/decode.go
@@ -252,6 +252,7 @@ var (
jsonUnmarshalerType = reflect.TypeOf((*json.Unmarshaler)(nil)).Elem()
textUnmarshalerType = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem()
boolType = reflect.TypeOf(true)
+ float64Type = reflect.TypeOf(float64(0))
)
var kind2bits = map[reflect.Kind]int{
@@ -687,7 +688,7 @@ func (dec *Decoder) decodeAny() any {
}
f64, err := num.Float64()
if err != nil {
- panic("should not happen")
+ dec.panicType("number "+buf.String(), float64Type, err)
}
return f64
case 't', 'f':
diff --git a/decode_scan_test.go b/decode_scan_test.go
index 5ad454f..1f04ead 100644
--- a/decode_scan_test.go
+++ b/decode_scan_test.go
@@ -105,6 +105,13 @@ func TestRuneTypeScanner(t *testing.T) {
{0, 0, RuneTypeEOF, nil},
{0, 0, RuneTypeEOF, nil},
}},
+ "syntax-error": {`[[0,]`, []ReadRuneTypeResult{
+ {'[', 1, RuneTypeArrayBeg, nil},
+ {'[', 1, RuneTypeArrayBeg, nil},
+ {'0', 1, RuneTypeNumberIntZero, nil},
+ {',', 1, RuneTypeArrayComma, nil},
+ {']', 1, RuneTypeError, &DecodeSyntaxError{Offset: 5, Err: fmt.Errorf("invalid character %q looking for beginning of value", ']')}},
+ }},
}
for tcName, tc := range testcases {
t.Run(tcName, func(t *testing.T) {
diff --git a/parse.go b/parse.go
index 77d1b08..954d3dc 100644
--- a/parse.go
+++ b/parse.go
@@ -238,6 +238,7 @@ type Parser struct {
//
// [ array: waiting for item to start or ']'
// a array: reading item / waiting for ',' or ']'
+ // ] array: waiting for item to start
//
// Within each element type, the stack item is replaced, not pushed.
//
@@ -454,12 +455,21 @@ func (par *Parser) HandleRune(c rune) (RuneType, error) {
par.pushState(RuneTypeError)
return par.HandleRune(c)
}
+ case RuneTypeArrayEnd: // waiting for item
+ switch c {
+ case 0x0020, 0x000A, 0x000D, 0x0009:
+ return RuneTypeSpace, nil
+ default:
+ par.replaceState(RuneTypeArrayComma)
+ par.pushState(RuneTypeError)
+ return par.HandleRune(c)
+ }
case RuneTypeArrayComma: // waiting for ',' or ']'
switch c {
case 0x0020, 0x000A, 0x000D, 0x0009:
return RuneTypeSpace, nil
case ',':
- par.replaceState(RuneTypeArrayBeg)
+ par.replaceState(RuneTypeArrayEnd)
return RuneTypeArrayComma, nil
case ']':
par.popState()