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 {
if typ.Kind() != reflect.Ptr || p == 0 {
if typ == nil || typ.Kind() != reflect.Ptr || p == 0 {
return &InvalidUnmarshalError{Type: rtype2type(typ)}
}
return nil

View File

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

View File

@ -44,25 +44,31 @@ func (d *unmarshalTextDecoder) decodeStream(s *stream, p unsafe.Pointer) error {
return err
}
src := s.buf[start:s.cursor]
switch src[0] {
case '[':
// cannot decode array value by unmarshal text
return &UnmarshalTypeError{
Value: "array",
Type: rtype2type(d.typ),
Offset: s.totalOffset(),
}
case '{':
// cannot decode object value by unmarshal text
return &UnmarshalTypeError{
Value: "object",
Type: rtype2type(d.typ),
Offset: s.totalOffset(),
}
case 'n':
if bytes.Equal(src, nullbytes) {
*(*unsafe.Pointer)(p) = nil
return nil
if len(src) > 0 {
switch src[0] {
case '[':
return &UnmarshalTypeError{
Value: "array",
Type: rtype2type(d.typ),
Offset: s.totalOffset(),
}
case '{':
return &UnmarshalTypeError{
Value: "object",
Type: rtype2type(d.typ),
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':
if bytes.Equal(src, nullbytes) {
*(*unsafe.Pointer)(p) = nil
return nil
}
}
}
dst := make([]byte, len(src))
@ -90,9 +96,32 @@ func (d *unmarshalTextDecoder) decode(buf []byte, cursor int64, p unsafe.Pointer
return 0, err
}
src := buf[start:end]
if bytes.Equal(src, nullbytes) {
*(*unsafe.Pointer)(p) = nil
return end, nil
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) {
*(*unsafe.Pointer)(p) = nil
return end, nil
}
}
}
if s, ok := unquoteBytes(src); ok {