2
0
Fork 0
mirror of https://github.com/ii64/sonic.git synced 2026-06-21 00:46:43 +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:
liu 2023-05-16 14:13:04 +08:00 committed by GitHub
parent d83abb5435
commit eaa70d4c25
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 74 additions and 3 deletions

View file

@ -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.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" , _AX, jit.Ptr(_VP, 8)) // MOVQ AX, 8(VP)
self.Emit("MOVQ" , _SI, jit.Ptr(_VP, 16)) // MOVQ SI, 16(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.Link("_index_{n}") // _index_{n}:
self.Emit("ADDQ" , jit.Imm(1), jit.Ptr(_VP, 8)) // ADDQ $1, 8(VP) 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.Ptr(_VP, 0), _VP) // MOVQ (VP), VP
self.Emit("MOVQ" , jit.Imm(int64(p.vlen())), _CX) // MOVQ ${p.vlen()}, CX self.Emit("MOVQ" , jit.Imm(int64(p.vlen())), _CX) // MOVQ ${p.vlen()}, CX
self.From("MULQ" , _CX) // MULQ CX self.From("MULQ" , _CX) // MULQ CX
self.Emit("ADDQ" , _AX, _VP) // ADDQ AX, VP self.Emit("ADDQ" , _AX, _VP) // ADDQ AX, VP
self.Link("_append_slice_end_{n}")
} }
func (self *_Assembler) _asm_OP_object_skip(_ *_Instr) { func (self *_Assembler) _asm_OP_object_skip(_ *_Instr) {

View file

@ -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_sp, _AX) // MOVQ sp, AX
self.Emit("MOVQ", _ARG_sl, _BX) // MOVQ sp, BX self.Emit("MOVQ", _ARG_sl, _BX) // MOVQ sp, BX
self.Emit("MOVQ" , _IC, _CX) // MOVQ IC, CX 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.Emit("MOVQ" , _ARG_fv, _R9) // MOVQ fv, R9
self.save(_REG_rt...) self.save(_REG_rt...)
self.Emit("MOVQ", _F_decodeTypedPointer, _IL) // MOVQ ${fn}, R11 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.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" , _BX, jit.Ptr(_VP, 8)) // MOVQ BX, 8(VP)
self.Emit("MOVQ" , _CX, jit.Ptr(_VP, 16)) // MOVQ CX, 16(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.Emit("MOVQ" , _BX, _AX) // MOVQ BX, AX
self.Link("_index_{n}") // _index_{n}: self.Link("_index_{n}") // _index_{n}:
self.Emit("ADDQ" , jit.Imm(1), jit.Ptr(_VP, 8)) // ADDQ $1, 8(VP) 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.Emit("MOVQ" , jit.Imm(int64(p.vlen())), _CX) // MOVQ ${p.vlen()}, CX
self.From("MULQ" , _CX) // MULQ CX self.From("MULQ" , _CX) // MULQ CX
self.Emit("ADDQ" , _AX, _VP) // ADDQ AX, VP self.Emit("ADDQ" , _AX, _VP) // ADDQ AX, VP
self.Link("_append_slice_end_{n}")
} }
func (self *_Assembler) _asm_OP_object_skip(_ *_Instr) { func (self *_Assembler) _asm_OP_object_skip(_ *_Instr) {

View file

@ -134,9 +134,9 @@ func TestSkipMismatchTypeError(t *testing.T) {
t.Fatal("invalid error") 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 obj, obj2 = &[]int{}, &[]int{}
var data = `["",1,true]` var data = `[""]`
d := NewDecoder(data) d := NewDecoder(data)
err := d.Decode(obj) err := d.Decode(obj)
err2 := json.Unmarshal([]byte(data), obj2) 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, len(data), d.i)
assert.Equal(t, obj2, obj) 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) { t.Run("map", func(t *testing.T) {
var obj, obj2 = &map[int]int{}, &map[int]int{} var obj, obj2 = &map[int]int{}, &map[int]int{}
var data = `{"true" : { },"1":1,"2" : true,"3":3}` var data = `{"true" : { },"1":1,"2" : true,"3":3}`