Fix decoding of invalid value

This commit is contained in:
Masaaki Goshima 2021-02-18 16:42:38 +09:00
parent 91c53cd3f7
commit 0288026fde
3 changed files with 52 additions and 27 deletions

View File

@ -78,7 +78,7 @@ func noescape(p unsafe.Pointer) unsafe.Pointer {
} }
func validateType(typ *rtype, p uintptr) error { func validateType(typ *rtype, p uintptr) error {
if typ.Kind() != reflect.Ptr || p == 0 { if typ == nil || typ.Kind() != reflect.Ptr || p == 0 {
return &InvalidUnmarshalError{Type: rtype2type(typ)} return &InvalidUnmarshalError{Type: rtype2type(typ)}
} }
return nil return nil

View File

@ -2475,7 +2475,6 @@ var invalidUnmarshalTests = []struct {
{(*int)(nil), "json: Unmarshal(nil *int)"}, {(*int)(nil), "json: Unmarshal(nil *int)"},
} }
/*
func TestInvalidUnmarshal(t *testing.T) { func TestInvalidUnmarshal(t *testing.T) {
buf := []byte(`{"a":"1"}`) buf := []byte(`{"a":"1"}`)
for _, tt := range invalidUnmarshalTests { for _, tt := range invalidUnmarshalTests {
@ -2489,7 +2488,6 @@ func TestInvalidUnmarshal(t *testing.T) {
} }
} }
} }
*/
var invalidUnmarshalTextTests = []struct { var invalidUnmarshalTextTests = []struct {
v interface{} v interface{}
@ -2501,7 +2499,6 @@ var invalidUnmarshalTextTests = []struct {
{new(net.IP), "json: cannot unmarshal number into Go value of type *net.IP"}, {new(net.IP), "json: cannot unmarshal number into Go value of type *net.IP"},
} }
/*
func TestInvalidUnmarshalText(t *testing.T) { func TestInvalidUnmarshalText(t *testing.T) {
buf := []byte(`123`) buf := []byte(`123`)
for _, tt := range invalidUnmarshalTextTests { for _, tt := range invalidUnmarshalTextTests {
@ -2515,7 +2512,6 @@ func TestInvalidUnmarshalText(t *testing.T) {
} }
} }
} }
*/
/* /*
// Test that string option is ignored for invalid types. // Test that string option is ignored for invalid types.

View File

@ -44,27 +44,33 @@ func (d *unmarshalTextDecoder) decodeStream(s *stream, p unsafe.Pointer) error {
return err return err
} }
src := s.buf[start:s.cursor] src := s.buf[start:s.cursor]
if len(src) > 0 {
switch src[0] { switch src[0] {
case '[': case '[':
// cannot decode array value by unmarshal text
return &UnmarshalTypeError{ return &UnmarshalTypeError{
Value: "array", Value: "array",
Type: rtype2type(d.typ), Type: rtype2type(d.typ),
Offset: s.totalOffset(), Offset: s.totalOffset(),
} }
case '{': case '{':
// cannot decode object value by unmarshal text
return &UnmarshalTypeError{ return &UnmarshalTypeError{
Value: "object", Value: "object",
Type: rtype2type(d.typ), Type: rtype2type(d.typ),
Offset: s.totalOffset(), Offset: s.totalOffset(),
} }
case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
return &UnmarshalTypeError{
Value: "number",
Type: rtype2type(d.typ),
Offset: s.totalOffset(),
}
case 'n': case 'n':
if bytes.Equal(src, nullbytes) { if bytes.Equal(src, nullbytes) {
*(*unsafe.Pointer)(p) = nil *(*unsafe.Pointer)(p) = nil
return nil return nil
} }
} }
}
dst := make([]byte, len(src)) dst := make([]byte, len(src))
copy(dst, src) copy(dst, src)
@ -90,10 +96,33 @@ func (d *unmarshalTextDecoder) decode(buf []byte, cursor int64, p unsafe.Pointer
return 0, err return 0, err
} }
src := buf[start:end] src := buf[start:end]
if len(src) > 0 {
switch src[0] {
case '[':
return 0, &UnmarshalTypeError{
Value: "array",
Type: rtype2type(d.typ),
Offset: start,
}
case '{':
return 0, &UnmarshalTypeError{
Value: "object",
Type: rtype2type(d.typ),
Offset: start,
}
case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
return 0, &UnmarshalTypeError{
Value: "number",
Type: rtype2type(d.typ),
Offset: start,
}
case 'n':
if bytes.Equal(src, nullbytes) { if bytes.Equal(src, nullbytes) {
*(*unsafe.Pointer)(p) = nil *(*unsafe.Pointer)(p) = nil
return end, nil return end, nil
} }
}
}
if s, ok := unquoteBytes(src); ok { if s, ok := unquoteBytes(src); ok {
src = s src = s