From 10de43128b876381c790f45bdcc20bb1c1d0b447 Mon Sep 17 00:00:00 2001 From: Nao Yonashiro Date: Fri, 12 Feb 2021 18:12:40 +0900 Subject: [PATCH 1/2] test: add test case of decode escaped string to empty interface --- decode_test.go | 6 ++++++ 1 file changed, 6 insertions(+) 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)) From 405201e4f9044fa9c46fe6ed8743fe9dac882730 Mon Sep 17 00:00:00 2001 From: Nao Yonashiro Date: Fri, 12 Feb 2021 18:13:07 +0900 Subject: [PATCH 2/2] fix: use stringDecoder for decode escaped string to empty interface --- decode_interface.go | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) 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)