mirror of
https://github.com/ii64/sonic.git
synced 2026-06-20 16:45:22 +08:00
fix: initialize the elem when slice grow in decode (#415)
* fix: check mismatch error after recusive * fix: initialize the elem when slice grow in decode --------- Co-authored-by: liuqiang <liuqiang.06@bytedance.com> Co-authored-by: Yi Duan <duanyi.aster@bytedance.com>
This commit is contained in:
parent
d83abb5435
commit
eaa70d4c25
3 changed files with 74 additions and 3 deletions
|
|
@ -1661,12 +1661,34 @@ func (self *_Assembler) _asm_OP_slice_append(p *_Instr) {
|
|||
self.WriteRecNotAX(8, _DI, jit.Ptr(_VP, 0), true, true)// MOVQ DI, (VP)
|
||||
self.Emit("MOVQ" , _AX, jit.Ptr(_VP, 8)) // MOVQ AX, 8(VP)
|
||||
self.Emit("MOVQ" , _SI, jit.Ptr(_VP, 16)) // MOVQ SI, 16(VP)
|
||||
|
||||
// because growslice not zero memory {oldcap, newlen} when append et not has ptrdata.
|
||||
// but we should zero it, avoid decode it as random values.
|
||||
if rt.UnpackType(p.vt()).PtrData == 0 {
|
||||
self.Emit("SUBQ" , _AX, _SI) // MOVQ AX, SI
|
||||
|
||||
self.Emit("ADDQ" , jit.Imm(1), jit.Ptr(_VP, 8)) // ADDQ $1, 8(VP)
|
||||
self.Emit("MOVQ" , _DI, _VP) // MOVQ DI, VP
|
||||
self.Emit("MOVQ" , jit.Imm(int64(p.vlen())), _CX) // MOVQ ${p.vlen()}, CX
|
||||
self.From("MULQ" , _CX) // MULQ CX
|
||||
self.Emit("ADDQ" , _AX, _VP) // ADDQ AX, VP
|
||||
|
||||
self.Emit("MOVQ" , _SI, _AX) // MOVQ SI, AX
|
||||
self.From("MULQ" , _CX) // MULQ CX
|
||||
self.Emit("MOVQ" , _AX, jit.Ptr(_SP, 8)) // MOVQ AX, 8(SP)
|
||||
|
||||
self.Emit("MOVQ" , _VP, jit.Ptr(_SP, 0)) // MOVQ VP, (SP)
|
||||
self.mem_clear_fn(true) // CALL_GO memclr{Has,NoHeap}
|
||||
self.Sjmp("JMP", "_append_slice_end_{n}") // JMP _append_slice_end_{n}
|
||||
}
|
||||
|
||||
self.Link("_index_{n}") // _index_{n}:
|
||||
self.Emit("ADDQ" , jit.Imm(1), jit.Ptr(_VP, 8)) // ADDQ $1, 8(VP)
|
||||
self.Emit("MOVQ" , jit.Ptr(_VP, 0), _VP) // MOVQ (VP), VP
|
||||
self.Emit("MOVQ" , jit.Imm(int64(p.vlen())), _CX) // MOVQ ${p.vlen()}, CX
|
||||
self.From("MULQ" , _CX) // MULQ CX
|
||||
self.Emit("ADDQ" , _AX, _VP) // ADDQ AX, VP
|
||||
self.Link("_append_slice_end_{n}")
|
||||
}
|
||||
|
||||
func (self *_Assembler) _asm_OP_object_skip(_ *_Instr) {
|
||||
|
|
|
|||
|
|
@ -1124,7 +1124,7 @@ func (self *_Assembler) decode_dynamic(vt obj.Addr, vp obj.Addr) {
|
|||
self.Emit("MOVQ", _ARG_sp, _AX) // MOVQ sp, AX
|
||||
self.Emit("MOVQ", _ARG_sl, _BX) // MOVQ sp, BX
|
||||
self.Emit("MOVQ" , _IC, _CX) // MOVQ IC, CX
|
||||
self.Emit("MOVQ" , _ST, _R8) // MOVQ ST, R8
|
||||
self.Emit("MOVQ" , _ST, _R8) // MOVQ ST, R8
|
||||
self.Emit("MOVQ" , _ARG_fv, _R9) // MOVQ fv, R9
|
||||
self.save(_REG_rt...)
|
||||
self.Emit("MOVQ", _F_decodeTypedPointer, _IL) // MOVQ ${fn}, R11
|
||||
|
|
@ -1646,6 +1646,28 @@ func (self *_Assembler) _asm_OP_slice_append(p *_Instr) {
|
|||
self.WritePtrAX(8, jit.Ptr(_VP, 0), false) // MOVQ AX, (VP)
|
||||
self.Emit("MOVQ" , _BX, jit.Ptr(_VP, 8)) // MOVQ BX, 8(VP)
|
||||
self.Emit("MOVQ" , _CX, jit.Ptr(_VP, 16)) // MOVQ CX, 16(VP)
|
||||
|
||||
// because growslice not zero memory {oldcap, newlen} when append et not has ptrdata.
|
||||
// but we should zero it, avoid decode it as random values.
|
||||
if rt.UnpackType(p.vt()).PtrData == 0 {
|
||||
self.Emit("MOVQ" , _CX, _DI) // MOVQ CX, DI
|
||||
self.Emit("SUBQ" , _BX, _DI) // MOVQ BX, DI
|
||||
|
||||
self.Emit("ADDQ" , jit.Imm(1), jit.Ptr(_VP, 8)) // ADDQ $1, 8(VP)
|
||||
self.Emit("MOVQ" , _AX, _VP) // MOVQ AX, VP
|
||||
self.Emit("MOVQ" , jit.Imm(int64(p.vlen())), _CX) // MOVQ ${p.vlen()}, CX
|
||||
self.Emit("MOVQ" , _BX, _AX) // MOVQ BX, AX
|
||||
self.From("MULQ" , _CX) // MULQ CX
|
||||
self.Emit("ADDQ" , _AX, _VP) // ADDQ AX, VP
|
||||
|
||||
self.Emit("MOVQ" , _DI, _AX) // MOVQ SI, AX
|
||||
self.From("MULQ" , _CX) // MULQ BX
|
||||
self.Emit("MOVQ" , _AX, _BX) // ADDQ AX, BX
|
||||
self.Emit("MOVQ" , _VP, _AX) // MOVQ VP, AX
|
||||
self.mem_clear_fn(true) // CALL_GO memclr{Has,NoHeap}
|
||||
self.Sjmp("JMP", "_append_slice_end_{n}")
|
||||
}
|
||||
|
||||
self.Emit("MOVQ" , _BX, _AX) // MOVQ BX, AX
|
||||
self.Link("_index_{n}") // _index_{n}:
|
||||
self.Emit("ADDQ" , jit.Imm(1), jit.Ptr(_VP, 8)) // ADDQ $1, 8(VP)
|
||||
|
|
@ -1653,6 +1675,7 @@ func (self *_Assembler) _asm_OP_slice_append(p *_Instr) {
|
|||
self.Emit("MOVQ" , jit.Imm(int64(p.vlen())), _CX) // MOVQ ${p.vlen()}, CX
|
||||
self.From("MULQ" , _CX) // MULQ CX
|
||||
self.Emit("ADDQ" , _AX, _VP) // ADDQ AX, VP
|
||||
self.Link("_append_slice_end_{n}")
|
||||
}
|
||||
|
||||
func (self *_Assembler) _asm_OP_object_skip(_ *_Instr) {
|
||||
|
|
|
|||
|
|
@ -134,9 +134,9 @@ func TestSkipMismatchTypeError(t *testing.T) {
|
|||
t.Fatal("invalid error")
|
||||
}
|
||||
})
|
||||
t.Run("array", func(t *testing.T) {
|
||||
t.Run("short array", func(t *testing.T) {
|
||||
var obj, obj2 = &[]int{}, &[]int{}
|
||||
var data = `["",1,true]`
|
||||
var data = `[""]`
|
||||
d := NewDecoder(data)
|
||||
err := d.Decode(obj)
|
||||
err2 := json.Unmarshal([]byte(data), obj2)
|
||||
|
|
@ -145,6 +145,32 @@ func TestSkipMismatchTypeError(t *testing.T) {
|
|||
// assert.Equal(t, len(data), d.i)
|
||||
assert.Equal(t, obj2, obj)
|
||||
})
|
||||
|
||||
t.Run("int ", func(t *testing.T) {
|
||||
var obj int = 123
|
||||
var obj2 int = 123
|
||||
var data = `[""]`
|
||||
d := NewDecoder(data)
|
||||
err := d.Decode(&obj)
|
||||
err2 := json.Unmarshal([]byte(data), &obj2)
|
||||
println(err.Error(), obj, obj2)
|
||||
assert.Equal(t, err2 == nil, err == nil)
|
||||
// assert.Equal(t, len(data), d.i)
|
||||
assert.Equal(t, obj2, obj)
|
||||
})
|
||||
|
||||
t.Run("array", func(t *testing.T) {
|
||||
var obj, obj2 = &[]int{}, &[]int{}
|
||||
var data = `["",true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true]`
|
||||
d := NewDecoder(data)
|
||||
err := d.Decode(obj)
|
||||
err2 := json.Unmarshal([]byte(data), obj2)
|
||||
// println(err2.Error())
|
||||
assert.Equal(t, err2 == nil, err == nil)
|
||||
// assert.Equal(t, len(data), d.i)
|
||||
assert.Equal(t, obj2, obj)
|
||||
})
|
||||
|
||||
t.Run("map", func(t *testing.T) {
|
||||
var obj, obj2 = &map[int]int{}, &map[int]int{}
|
||||
var data = `{"true" : { },"1":1,"2" : true,"3":3}`
|
||||
|
|
|
|||
Loading…
Reference in a new issue