2
0
Fork 0
mirror of https://github.com/ii64/sonic.git synced 2026-06-21 00:46:43 +08:00

fix: return error on stack overflow instead of panicking

This commit is contained in:
chenzhuoyu 2021-06-24 12:19:51 +08:00 committed by Oxygen
parent 59be0c7b33
commit 955ab75cf5
4 changed files with 23 additions and 32 deletions

View file

@ -2365,7 +2365,7 @@ func TestUnmarshalMaxDepth(t *testing.T) {
},
{
name: "ObjectOverMaxNestingDepth",
data: `{"a":` + strings.Repeat(`{"a":`, 65536) + `0` + strings.Repeat(`}`, 65536) + `}`,
data: `{"a":` + strings.Repeat(`{"a":`, 65537) + `0` + strings.Repeat(`}`, 65537) + `}`,
errMaxDepth: true,
},
{
@ -2379,23 +2379,22 @@ func TestUnmarshalMaxDepth(t *testing.T) {
name string
newValue func() interface{}
}{
// FIXME: support these two cases
// {
// name: "unstructured",
// newValue: func() interface{} {
// var v interface{}
// return &v
// },
// },
// {
// name: "typed named field",
// newValue: func() interface{} {
// v := struct {
// A interface{} `json:"a"`
// }{}
// return &v
// },
// },
{
name: "unstructured",
newValue: func() interface{} {
var v interface{}
return &v
},
},
{
name: "typed named field",
newValue: func() interface{} {
v := struct {
A interface{} `json:"a"`
}{}
return &v
},
},
{
name: "typed missing field",
newValue: func() interface{} {

View file

@ -144,12 +144,12 @@ var (
_V_max = jit.Imm(int64(types.V_MAX))
_E_eof = jit.Imm(int64(types.ERR_EOF))
_E_invalid = jit.Imm(int64(types.ERR_INVALID_CHAR))
_E_recurse = jit.Imm(int64(types.ERR_RECURSE_EXCEED_MAX))
)
var (
_F_convTslice = jit.Func(convTslice)
_F_convTstring = jit.Func(convTstring)
_F_stack_exceed = jit.Func(stack_exceed)
_F_invalid_vtype = jit.Func(invalid_vtype)
)
@ -596,6 +596,9 @@ func (self *_ValueDecoder) compile() {
self.Sjmp("JMP" , "_array_append") // JMP _array_append
/* error handlers */
self.Link("_stack_overflow")
self.Emit("MOVL" , _E_recurse, _EP) // MOVQ _E_recurse, EP
self.Sjmp("JMP" , "_error") // JMP _error
self.Link("_vtype_error") // _vtype_error:
self.Emit("MOVQ" , _DI, _IC) // MOVQ DI, IC
self.Emit("MOVL" , _E_invalid, _EP) // MOVL _E_invalid, EP
@ -621,12 +624,6 @@ func (self *_ValueDecoder) compile() {
self.call(_F_invalid_vtype) // CALL invalid_type
self.Emit("UD2") // UD2
/* stack overflow, never returns */
self.Link("_stack_overflow")
self.Emit("MOVQ", _CX, jit.Ptr(_SP, 0)) // MOVQ CX, (SP)
self.call(_F_stack_exceed) // CALL stack_exceed
self.Emit("UD2") // UD2
/* switch jump table */
self.Link("_switch_table") // _switch_table:
self.Sref("_decode_V_EOF", 0) // SREF &_decode_V_EOF, $0
@ -663,11 +660,6 @@ var (
_subr_decode_value = new(_ValueDecoder).build()
)
//go:nosplit
func stack_exceed(n int) {
panic(fmt.Sprintf("stack size exceeds limit %d: %d", types.MAX_RECURSE, n))
}
//go:nosplit
func invalid_vtype(vt types.ValueType) {
throw(fmt.Sprintf("invalid value type: %d", vt))

View file

@ -27,7 +27,7 @@ import (
const (
_MinSlice = 16
_MaxStack = 262144 // 256k slots
_MaxStack = 65536 // 64k slots
)
const (

View file

@ -28,6 +28,7 @@ func TestIssue27_EmptySlice(t *testing.T) {
_ = Pretouch(reflect.TypeOf([]*int{}))
wg := sync.WaitGroup{}
for i := 0; i < 1000; i++ {
wg.Add(1)
go func() {
defer wg.Done()
v := make([]*int, 16)
@ -35,7 +36,6 @@ func TestIssue27_EmptySlice(t *testing.T) {
require.NoError(t, err)
require.Equal(t, []*int{nil, nil}, v)
}()
wg.Add(1)
}
wg.Wait()
}