Skip to content

Commit

Permalink
fix: initialize the elem when slice grow in decode (#415)
Browse files Browse the repository at this point in the history
* 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>
  • Loading branch information
3 people authored May 16, 2023
1 parent d83abb5 commit eaa70d4
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 2 deletions.
22 changes: 22 additions & 0 deletions decoder/assembler_amd64_go116.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
25 changes: 24 additions & 1 deletion decoder/assembler_amd64_go117.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -1646,13 +1646,36 @@ 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)
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) {
Expand Down
28 changes: 27 additions & 1 deletion decoder/decoder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,9 +134,34 @@ func TestSkipMismatchTypeError(t *testing.T) {
t.Fatal("invalid error")
}
})
t.Run("short array", func(t *testing.T) {
var obj, obj2 = &[]int{}, &[]int{}
var data = `[""]`
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("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 = `["",1,true]`
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)
Expand All @@ -145,6 +170,7 @@ func TestSkipMismatchTypeError(t *testing.T) {
// 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}`
Expand Down

0 comments on commit eaa70d4

Please sign in to comment.