Merge pull request #136 from goccy/feature/fix-null-string

Fix decoding of type of null string
This commit is contained in:
Masaaki Goshima 2021-02-16 23:48:22 +09:00 committed by GitHub
commit 72cdc2a1d5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 22 additions and 7 deletions

View File

@ -106,7 +106,7 @@ func decodeCompileMapKey(typ *rtype, structName, fieldName string, structTypeToD
case *stringDecoder, *interfaceDecoder: case *stringDecoder, *interfaceDecoder:
return dec, nil return dec, nil
case *boolDecoder, *intDecoder, *uintDecoder, *numberDecoder: case *boolDecoder, *intDecoder, *uintDecoder, *numberDecoder:
return newWrappedStringDecoder(dec, structName, fieldName), nil return newWrappedStringDecoder(typ, dec, structName, fieldName), nil
case *ptrDecoder: case *ptrDecoder:
dec = t.dec dec = t.dec
default: default:
@ -393,7 +393,7 @@ func decodeCompileStruct(typ *rtype, structName, fieldName string, structTypeToD
} }
} else { } else {
if tag.isString { if tag.isString {
dec = newWrappedStringDecoder(dec, structName, field.Name) dec = newWrappedStringDecoder(type2rtype(field.Type), dec, structName, field.Name)
} }
var key string var key string
if tag.key != "" { if tag.key != "" {

View File

@ -233,7 +233,7 @@ func (d *stringDecoder) decodeStreamByte(s *stream) ([]byte, error) {
if err := nullBytes(s); err != nil { if err := nullBytes(s); err != nil {
return nil, err return nil, err
} }
return []byte{}, nil return nil, nil
case nul: case nul:
if s.read() { if s.read() {
continue 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) return nil, 0, errInvalidCharacter(buf[cursor+3], "null", cursor)
} }
cursor += 4 cursor += 4
return []byte{}, cursor, nil return nil, cursor, nil
default: default:
goto ERROR goto ERROR
} }

View File

@ -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). // 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). // It should also not be an error (issue 2540, issue 8587).
func TestNullString(t *testing.T) { 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) t.Fatalf("after Unmarshal, s.B=%d, s.C=%p, want 1, nil", s.B, s.C)
} }
} }
*/
func intp(x int) *int { func intp(x int) *int {
p := new(int) p := new(int)

View File

@ -1,22 +1,27 @@
package json package json
import ( import (
"reflect"
"unsafe" "unsafe"
) )
type wrappedStringDecoder struct { type wrappedStringDecoder struct {
typ *rtype
dec decoder dec decoder
stringDecoder *stringDecoder stringDecoder *stringDecoder
structName string structName string
fieldName 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{ return &wrappedStringDecoder{
typ: typ,
dec: dec, dec: dec,
stringDecoder: newStringDecoder(structName, fieldName), stringDecoder: newStringDecoder(structName, fieldName),
structName: structName, structName: structName,
fieldName: fieldName, fieldName: fieldName,
isPtrType: typ.Kind() == reflect.Ptr,
} }
} }
@ -25,6 +30,12 @@ func (d *wrappedStringDecoder) decodeStream(s *stream, p unsafe.Pointer) error {
if err != nil { if err != nil {
return err return err
} }
if bytes == nil {
if d.isPtrType {
*(*unsafe.Pointer)(p) = nil
}
return nil
}
b := make([]byte, len(bytes)+1) b := make([]byte, len(bytes)+1)
copy(b, bytes) copy(b, bytes)
if _, err := d.dec.decode(b, 0, p); err != nil { 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 { if err != nil {
return 0, err return 0, err
} }
if bytes == nil {
if d.isPtrType {
*(*unsafe.Pointer)(p) = nil
}
return c, nil
}
bytes = append(bytes, nul) bytes = append(bytes, nul)
if _, err := d.dec.decode(bytes, 0, p); err != nil { if _, err := d.dec.decode(bytes, 0, p); err != nil {
return 0, err return 0, err