diff --git a/json/codec.go b/json/codec.go index e06e72b..1ef84f5 100644 --- a/json/codec.go +++ b/json/codec.go @@ -156,7 +156,7 @@ func constructCodec(t reflect.Type, seen map[reflect.Type]*structType, canAddr b c = codec{encode: encoder.encodeString, decode: decoder.decodeString} case reflect.Interface: - c = codec{encode: encoder.encodeInterface, decode: constructNonEmptyInterfaceDecoderFunc(t)} + c = codec{encode: encoder.encodeInterface, decode: constructMaybeEmptyInterfaceDecoderFunc(t)} case reflect.Array: c = constructArrayCodec(t, seen, canAddr) @@ -711,9 +711,9 @@ func constructPointerDecodeFunc(t reflect.Type, decode decodeFunc) decodeFunc { } } -func constructNonEmptyInterfaceDecoderFunc(t reflect.Type) decodeFunc { +func constructMaybeEmptyInterfaceDecoderFunc(t reflect.Type) decodeFunc { return func(d decoder, b []byte, p unsafe.Pointer) ([]byte, error) { - return d.decodeNonEmptyInterface(b, p, t) + return d.decodeMaybeEmptyInterface(b, p, t) } } diff --git a/json/decode.go b/json/decode.go index 14010d4..e01b444 100644 --- a/json/decode.go +++ b/json/decode.go @@ -1087,7 +1087,7 @@ func (d decoder) decodeInterface(b []byte, p unsafe.Pointer) ([]byte, error) { return b, nil } -func (d decoder) decodeNonEmptyInterface(b []byte, p unsafe.Pointer, t reflect.Type) ([]byte, error) { +func (d decoder) decodeMaybeEmptyInterface(b []byte, p unsafe.Pointer, t reflect.Type) ([]byte, error) { if hasNullPrefix(b) { *(*interface{})(p) = nil return b[4:], nil @@ -1097,6 +1097,8 @@ func (d decoder) decodeNonEmptyInterface(b []byte, p unsafe.Pointer, t reflect.T if e := x.Elem(); e.Kind() == reflect.Ptr { return Parse(b, e.Interface(), d.flags) } + } else if t.NumMethod() == 0 { // empty interface + return Parse(b, (*interface{})(p), d.flags) } return d.decodeUnmarshalTypeError(b, p, t) diff --git a/json/json_test.go b/json/json_test.go index c197a5c..8c430de 100644 --- a/json/json_test.go +++ b/json/json_test.go @@ -1464,3 +1464,14 @@ func TestGithubIssue23(t *testing.T) { } }) } + +func TestGithubIssue26(t *testing.T) { + type interfaceType interface{} + + var value interfaceType + var data = []byte(`{}`) + + if err := Unmarshal(data, &value); err != nil { + t.Error(err) + } +}