Skip to content

Commit

Permalink
fix: check mismatch error after recursive (#407)
Browse files Browse the repository at this point in the history
* fix: check mismatch error after recusive

* fix: add tests

* format

---------

Co-authored-by: liuqiang <liuqiang.06@bytedance.com>
  • Loading branch information
liuq19 and liuq19 committed May 6, 2023
1 parent cdd8937 commit ebbe758
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 6 deletions.
15 changes: 13 additions & 2 deletions decoder/assembler_amd64_go116.go
Expand Up @@ -458,6 +458,7 @@ var (
var (
_V_stackOverflow = jit.Imm(int64(uintptr(unsafe.Pointer(&stackOverflow))))
_I_json_UnsupportedValueError = jit.Itab(_T_error, reflect.TypeOf(new(json.UnsupportedValueError)))
_I_json_MismatchTypeError = jit.Itab(_T_error, reflect.TypeOf(new(MismatchTypeError)))
)

func (self *_Assembler) type_error() {
Expand All @@ -472,6 +473,10 @@ func (self *_Assembler) type_error() {

func (self *_Assembler) mismatch_error() {
self.Link(_LB_mismatch_error) // _type_error:
self.Emit("MOVQ", _VAR_et, _ET) // MOVQ _VAR_et, _ET
self.Emit("MOVQ", _VAR_ic, _EP) // MOVQ _VAR_ic, _EP
self.Emit("CMPQ", _ET, _I_json_MismatchTypeError) // CMPQ _ET, _I_json_MismatchType
self.Sjmp("JE" , _LB_error) // JE _LB_error
self.Emit("MOVQ", _ARG_sp, _AX)
self.Emit("MOVQ", _AX, jit.Ptr(_SP, 0)) // MOVQ AX, (SP)
self.Emit("MOVQ", _ARG_sl, _CX)
Expand Down Expand Up @@ -1128,9 +1133,15 @@ func (self *_Assembler) decode_dynamic(vt obj.Addr, vp obj.Addr) {
self.call_go(_F_decodeTypedPointer) // CALL_GO decodeTypedPointer
self.Emit("MOVQ" , jit.Ptr(_SP, 64), _ET) // MOVQ 64(SP), ET
self.Emit("MOVQ" , jit.Ptr(_SP, 72), _EP) // MOVQ 72(SP), EP
self.Emit("TESTQ", _ET, _ET) // TESTQ ET, ET
self.Sjmp("JNZ" , _LB_error) // JNZ _error
self.Emit("MOVQ" , jit.Ptr(_SP, 56), _IC) // MOVQ 56(SP), IC
self.Emit("TESTQ", _ET, _ET) // TESTQ ET, ET
self.Sjmp("JE", "_decode_dynamic_end_{n}") // JE, _decode_dynamic_end_{n}
self.Emit("CMPQ", _ET, _I_json_MismatchTypeError)
self.Sjmp("JNE" , _LB_error) // JNE LB_error
self.Emit("MOVQ", _EP, _VAR_ic) // MOVQ EP, VAR_ic
self.Emit("MOVQ", _ET, _VAR_et) // MOVQ ET, VAR_et
self.Link("_decode_dynamic_end_{n}")

}

/** OpCode Assembler Functions **/
Expand Down
18 changes: 14 additions & 4 deletions decoder/assembler_amd64_go117.go
Expand Up @@ -348,8 +348,8 @@ func (self *_Assembler) epilogue() {
self.Emit("MOVQ", _EP, _CX) // MOVQ BX, CX
self.Emit("MOVQ", _ET, _BX) // MOVQ AX, BX
self.Emit("MOVQ", _IC, _AX) // MOVQ IC, AX
self.Emit("MOVQ", jit.Imm(0), _ARG_sp) // MOVQ $0, sv.p<>+48(FP)
self.Emit("MOVQ", jit.Imm(0), _ARG_vp) // MOVQ $0, sv.p<>+48(FP)
self.Emit("MOVQ", jit.Imm(0), _ARG_sp) // MOVQ $0, sv.p<>+48(FP)
self.Emit("MOVQ", jit.Imm(0), _ARG_vp) // MOVQ $0, sv.p<>+48(FP)
self.Emit("MOVQ", jit.Imm(0), _ARG_sv_p) // MOVQ $0, sv.p<>+48(FP)
self.Emit("MOVQ", jit.Imm(0), _ARG_vk) // MOVQ $0, vk<>+64(FP)
self.Emit("MOVQ", jit.Ptr(_SP, _FP_offs), _BP) // MOVQ _FP_offs(SP), BP
Expand Down Expand Up @@ -480,6 +480,7 @@ var (
var (
_V_stackOverflow = jit.Imm(int64(uintptr(unsafe.Pointer(&stackOverflow))))
_I_json_UnsupportedValueError = jit.Itab(_T_error, reflect.TypeOf(new(json.UnsupportedValueError)))
_I_json_MismatchTypeError = jit.Itab(_T_error, reflect.TypeOf(new(MismatchTypeError)))
)

func (self *_Assembler) type_error() {
Expand All @@ -489,7 +490,11 @@ func (self *_Assembler) type_error() {
}

func (self *_Assembler) mismatch_error() {
self.Link(_LB_mismatch_error) // _type_error:
self.Link(_LB_mismatch_error) // _type_error:
self.Emit("MOVQ", _VAR_et, _ET) // MOVQ _VAR_et, _ET
self.Emit("MOVQ", _VAR_ic, _EP) // MOVQ _VAR_ic, _EP
self.Emit("CMPQ", _ET, _I_json_MismatchTypeError) // CMPQ _ET, _I_json_MismatchType
self.Sjmp("JE" , _LB_error) // JE _LB_error
self.Emit("MOVQ", _ARG_sp, _AX)
self.Emit("MOVQ", _ARG_sl, _BX)
self.Emit("MOVQ", _VAR_ic, _CX)
Expand Down Expand Up @@ -1129,7 +1134,12 @@ func (self *_Assembler) decode_dynamic(vt obj.Addr, vp obj.Addr) {
self.Emit("MOVQ" , _BX, _ET) // MOVQ BX, ET
self.Emit("MOVQ" , _CX, _EP) // MOVQ CX, EP
self.Emit("TESTQ", _ET, _ET) // TESTQ ET, ET
self.Sjmp("JNZ" , _LB_error) // JNZ _error
self.Sjmp("JE", "_decode_dynamic_end_{n}") // JE, _decode_dynamic_end_{n}
self.Emit("CMPQ", _ET, _I_json_MismatchTypeError)
self.Sjmp("JNE" , _LB_error) // JNE LB_error
self.Emit("MOVQ", _EP, _VAR_ic) // MOVQ EP, VAR_ic
self.Emit("MOVQ", _ET, _VAR_et) // MOVQ ET, VAR_et
self.Link("_decode_dynamic_end_{n}")
}

/** OpCode Assembler Functions **/
Expand Down
46 changes: 46 additions & 0 deletions issue_test/issue406_test.go
@@ -0,0 +1,46 @@
/*
* Copyright 2023 ByteDance Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package issue_test

import (
`testing`
`encoding/json`
`github.com/stretchr/testify/require`
`github.com/bytedance/sonic`
)

type FooId struct {
Id int `json:"id"`
}

func TestUnmarshalErrorInMapSlice(t *testing.T) {
var a, b map[string][]FooId
mapdata := `{"ptrslice": [{"id": "1"}, {"id": "2"}, {"id": "3"}, {"id": "4"}]}`
se := json.Unmarshal([]byte(mapdata), &a)
je := sonic.Unmarshal([]byte(mapdata), &b)
require.Equal(t, se == nil, je == nil);
require.Equal(t, a, b);
}

func TestUnmarshalErrorInSlice(t *testing.T) {
var a, b []*FooId
slicedata := `[{"id": "1"}, {"id": "2"}, {"id": "3"}, {"id": 4}]`
je := json.Unmarshal([]byte(slicedata), &a)
se := sonic.Unmarshal([]byte(slicedata), &b)
require.Equal(t, se == nil, je == nil);
require.Equal(t, a, b);
}

0 comments on commit ebbe758

Please sign in to comment.