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:
parent
59be0c7b33
commit
955ab75cf5
4 changed files with 23 additions and 32 deletions
|
|
@ -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{} {
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ import (
|
|||
|
||||
const (
|
||||
_MinSlice = 16
|
||||
_MaxStack = 262144 // 256k slots
|
||||
_MaxStack = 65536 // 64k slots
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue