mirror of https://github.com/goccy/go-json.git
Merge pull request #184 from goccy/feature/validate-end-buf
Fix decoding of invalid top level value
This commit is contained in:
commit
deec2b2b0d
25
decode.go
25
decode.go
|
@ -2,6 +2,7 @@ package json
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding"
|
"encoding"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
@ -40,10 +41,11 @@ func unmarshal(data []byte, v interface{}) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if _, err := dec.decode(src, 0, 0, header.ptr); err != nil {
|
cursor, err := dec.decode(src, 0, 0, header.ptr)
|
||||||
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return validateEndBuf(src, cursor)
|
||||||
}
|
}
|
||||||
|
|
||||||
func unmarshalNoEscape(data []byte, v interface{}) error {
|
func unmarshalNoEscape(data []byte, v interface{}) error {
|
||||||
|
@ -59,10 +61,27 @@ func unmarshalNoEscape(data []byte, v interface{}) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if _, err := dec.decode(src, 0, 0, noescape(header.ptr)); err != nil {
|
cursor, err := dec.decode(src, 0, 0, noescape(header.ptr))
|
||||||
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
return validateEndBuf(src, cursor)
|
||||||
|
}
|
||||||
|
|
||||||
|
func validateEndBuf(src []byte, cursor int64) error {
|
||||||
|
for {
|
||||||
|
switch src[cursor] {
|
||||||
|
case ' ', '\t', '\n', '\r':
|
||||||
|
cursor++
|
||||||
|
continue
|
||||||
|
case nul:
|
||||||
return nil
|
return nil
|
||||||
|
}
|
||||||
|
return errSyntax(
|
||||||
|
fmt.Sprintf("invalid character '%c' after top-level value", src[cursor]),
|
||||||
|
cursor+1,
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//nolint:staticcheck
|
//nolint:staticcheck
|
||||||
|
|
|
@ -3,6 +3,7 @@ package json_test
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding"
|
"encoding"
|
||||||
|
stdjson "encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"image"
|
"image"
|
||||||
|
@ -2929,3 +2930,24 @@ func TestDecodeSlice(t *testing.T) {
|
||||||
t.Fatal("invaid address")
|
t.Fatal("invaid address")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestInvalidTopLevelValue(t *testing.T) {
|
||||||
|
t.Run("invalid end of buffer", func(t *testing.T) {
|
||||||
|
var v struct{}
|
||||||
|
if err := stdjson.Unmarshal([]byte(`{}0`), &v); err == nil {
|
||||||
|
t.Fatal("expected error")
|
||||||
|
}
|
||||||
|
if err := json.Unmarshal([]byte(`{}0`), &v); err == nil {
|
||||||
|
t.Fatal("expected error")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
t.Run("invalid object", func(t *testing.T) {
|
||||||
|
var v interface{}
|
||||||
|
if err := stdjson.Unmarshal([]byte(`{"a":4}{"a"5}`), &v); err == nil {
|
||||||
|
t.Fatal("expected error")
|
||||||
|
}
|
||||||
|
if err := json.Unmarshal([]byte(`{"a":4}{"a"5}`), &v); err == nil {
|
||||||
|
t.Fatal("expected error")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue