From 0288026fdef373c1b3b7830f435be8c47b7702c0 Mon Sep 17 00:00:00 2001 From: Masaaki Goshima Date: Thu, 18 Feb 2021 16:42:38 +0900 Subject: [PATCH] Fix decoding of invalid value --- decode.go | 2 +- decode_test.go | 4 --- decode_unmarshal_text.go | 73 ++++++++++++++++++++++++++++------------ 3 files changed, 52 insertions(+), 27 deletions(-) diff --git a/decode.go b/decode.go index 84ad4f0..c700579 100644 --- a/decode.go +++ b/decode.go @@ -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 diff --git a/decode_test.go b/decode_test.go index 4a4a171..742143d 100644 --- a/decode_test.go +++ b/decode_test.go @@ -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. diff --git a/decode_unmarshal_text.go b/decode_unmarshal_text.go index 1cde243..33469a4 100644 --- a/decode_unmarshal_text.go +++ b/decode_unmarshal_text.go @@ -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 {