diff --git a/decode_interface.go b/decode_interface.go index bc4dadd..a46abe5 100644 --- a/decode_interface.go +++ b/decode_interface.go @@ -275,23 +275,15 @@ func (d *interfaceDecoder) decodeEmptyInterface(buf []byte, cursor int64, p unsa *(*interface{})(p) = v }).decode(buf, cursor, p) case '"': - cursor++ - start := cursor - for { - switch buf[cursor] { - case '\\': - cursor++ - continue - case '"': - literal := buf[start:cursor] - cursor++ - **(**interface{})(unsafe.Pointer(&p)) = *(*string)(unsafe.Pointer(&literal)) - return cursor, nil - case nul: - return 0, errUnexpectedEndOfJSON("string", cursor) - } - cursor++ + var v string + ptr := unsafe.Pointer(&v) + dec := newStringDecoder(d.structName, d.fieldName) + cursor, err := dec.decode(buf, cursor, ptr) + if err != nil { + return 0, err } + **(**interface{})(unsafe.Pointer(&p)) = v + return cursor, nil case 't': if cursor+3 >= int64(len(buf)) { return 0, errUnexpectedEndOfJSON("bool(true)", cursor) diff --git a/decode_test.go b/decode_test.go index eb60c60..e8f9322 100644 --- a/decode_test.go +++ b/decode_test.go @@ -197,6 +197,12 @@ func Test_Decoder(t *testing.T) { assertEq(t, "interface.kind", "string", reflect.TypeOf(v).Kind().String()) assertEq(t, "interface", `hello`, fmt.Sprint(v)) }) + t.Run("escaped string", func(t *testing.T) { + var v interface{} + assertErr(t, json.Unmarshal([]byte(`"he\"llo"`), &v)) + assertEq(t, "interface.kind", "string", reflect.TypeOf(v).Kind().String()) + assertEq(t, "interface", `he"llo`, fmt.Sprint(v)) + }) t.Run("bool", func(t *testing.T) { var v interface{} assertErr(t, json.Unmarshal([]byte(`true`), &v))