From 644ac4a69286826240052e89b1029f507744a0b5 Mon Sep 17 00:00:00 2001 From: Masaaki Goshima Date: Tue, 16 Feb 2021 11:46:00 +0900 Subject: [PATCH] Fix decoding of type of null string --- decode_compile.go | 4 ++-- decode_string.go | 4 ++-- decode_test.go | 2 -- decode_wrapped_string.go | 19 ++++++++++++++++++- 4 files changed, 22 insertions(+), 7 deletions(-) diff --git a/decode_compile.go b/decode_compile.go index 1398850..b563d50 100644 --- a/decode_compile.go +++ b/decode_compile.go @@ -106,7 +106,7 @@ func decodeCompileMapKey(typ *rtype, structName, fieldName string, structTypeToD case *stringDecoder, *interfaceDecoder: return dec, nil case *boolDecoder, *intDecoder, *uintDecoder, *numberDecoder: - return newWrappedStringDecoder(dec, structName, fieldName), nil + return newWrappedStringDecoder(typ, dec, structName, fieldName), nil case *ptrDecoder: dec = t.dec default: @@ -393,7 +393,7 @@ func decodeCompileStruct(typ *rtype, structName, fieldName string, structTypeToD } } else { if tag.isString { - dec = newWrappedStringDecoder(dec, structName, field.Name) + dec = newWrappedStringDecoder(type2rtype(field.Type), dec, structName, field.Name) } var key string if tag.key != "" { diff --git a/decode_string.go b/decode_string.go index 2dcd2e5..1d30b5d 100644 --- a/decode_string.go +++ b/decode_string.go @@ -233,7 +233,7 @@ func (d *stringDecoder) decodeStreamByte(s *stream) ([]byte, error) { if err := nullBytes(s); err != nil { return nil, err } - return []byte{}, nil + return nil, nil case nul: if s.read() { continue @@ -322,7 +322,7 @@ func (d *stringDecoder) decodeByte(buf []byte, cursor int64) ([]byte, int64, err return nil, 0, errInvalidCharacter(buf[cursor+3], "null", cursor) } cursor += 4 - return []byte{}, cursor, nil + return nil, cursor, nil default: goto ERROR } diff --git a/decode_test.go b/decode_test.go index e8f9322..645a852 100644 --- a/decode_test.go +++ b/decode_test.go @@ -2052,7 +2052,6 @@ func TestEmptyString(t *testing.T) { } } -/* // Test that a null for ,string is not replaced with the previous quoted string (issue 7046). // It should also not be an error (issue 2540, issue 8587). func TestNullString(t *testing.T) { @@ -2074,7 +2073,6 @@ func TestNullString(t *testing.T) { t.Fatalf("after Unmarshal, s.B=%d, s.C=%p, want 1, nil", s.B, s.C) } } -*/ func intp(x int) *int { p := new(int) diff --git a/decode_wrapped_string.go b/decode_wrapped_string.go index d1b2cf4..223ceed 100644 --- a/decode_wrapped_string.go +++ b/decode_wrapped_string.go @@ -1,22 +1,27 @@ package json import ( + "reflect" "unsafe" ) type wrappedStringDecoder struct { + typ *rtype dec decoder stringDecoder *stringDecoder structName string fieldName string + isPtrType bool } -func newWrappedStringDecoder(dec decoder, structName, fieldName string) *wrappedStringDecoder { +func newWrappedStringDecoder(typ *rtype, dec decoder, structName, fieldName string) *wrappedStringDecoder { return &wrappedStringDecoder{ + typ: typ, dec: dec, stringDecoder: newStringDecoder(structName, fieldName), structName: structName, fieldName: fieldName, + isPtrType: typ.Kind() == reflect.Ptr, } } @@ -25,6 +30,12 @@ func (d *wrappedStringDecoder) decodeStream(s *stream, p unsafe.Pointer) error { if err != nil { return err } + if bytes == nil { + if d.isPtrType { + *(*unsafe.Pointer)(p) = nil + } + return nil + } b := make([]byte, len(bytes)+1) copy(b, bytes) if _, err := d.dec.decode(b, 0, p); err != nil { @@ -38,6 +49,12 @@ func (d *wrappedStringDecoder) decode(buf []byte, cursor int64, p unsafe.Pointer if err != nil { return 0, err } + if bytes == nil { + if d.isPtrType { + *(*unsafe.Pointer)(p) = nil + } + return c, nil + } bytes = append(bytes, nul) if _, err := d.dec.decode(bytes, 0, p); err != nil { return 0, err