2
0
Fork 0
mirror of https://github.com/ii64/sonic.git synced 2026-06-22 17:36:48 +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", name: "ObjectOverMaxNestingDepth",
data: `{"a":` + strings.Repeat(`{"a":`, 65536) + `0` + strings.Repeat(`}`, 65536) + `}`, data: `{"a":` + strings.Repeat(`{"a":`, 65537) + `0` + strings.Repeat(`}`, 65537) + `}`,
errMaxDepth: true, errMaxDepth: true,
}, },
{ {
@ -2379,23 +2379,22 @@ func TestUnmarshalMaxDepth(t *testing.T) {
name string name string
newValue func() interface{} newValue func() interface{}
}{ }{
// FIXME: support these two cases {
// { name: "unstructured",
// name: "unstructured", newValue: func() interface{} {
// newValue: func() interface{} { var v interface{}
// var v interface{} return &v
// return &v },
// }, },
// }, {
// { name: "typed named field",
// name: "typed named field", newValue: func() interface{} {
// newValue: func() interface{} { v := struct {
// v := struct { A interface{} `json:"a"`
// A interface{} `json:"a"` }{}
// }{} return &v
// return &v },
// }, },
// },
{ {
name: "typed missing field", name: "typed missing field",
newValue: func() interface{} { newValue: func() interface{} {

View file

@ -144,12 +144,12 @@ var (
_V_max = jit.Imm(int64(types.V_MAX)) _V_max = jit.Imm(int64(types.V_MAX))
_E_eof = jit.Imm(int64(types.ERR_EOF)) _E_eof = jit.Imm(int64(types.ERR_EOF))
_E_invalid = jit.Imm(int64(types.ERR_INVALID_CHAR)) _E_invalid = jit.Imm(int64(types.ERR_INVALID_CHAR))
_E_recurse = jit.Imm(int64(types.ERR_RECURSE_EXCEED_MAX))
) )
var ( var (
_F_convTslice = jit.Func(convTslice) _F_convTslice = jit.Func(convTslice)
_F_convTstring = jit.Func(convTstring) _F_convTstring = jit.Func(convTstring)
_F_stack_exceed = jit.Func(stack_exceed)
_F_invalid_vtype = jit.Func(invalid_vtype) _F_invalid_vtype = jit.Func(invalid_vtype)
) )
@ -596,6 +596,9 @@ func (self *_ValueDecoder) compile() {
self.Sjmp("JMP" , "_array_append") // JMP _array_append self.Sjmp("JMP" , "_array_append") // JMP _array_append
/* error handlers */ /* 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.Link("_vtype_error") // _vtype_error:
self.Emit("MOVQ" , _DI, _IC) // MOVQ DI, IC self.Emit("MOVQ" , _DI, _IC) // MOVQ DI, IC
self.Emit("MOVL" , _E_invalid, _EP) // MOVL _E_invalid, EP 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.call(_F_invalid_vtype) // CALL invalid_type
self.Emit("UD2") // UD2 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 */ /* switch jump table */
self.Link("_switch_table") // _switch_table: self.Link("_switch_table") // _switch_table:
self.Sref("_decode_V_EOF", 0) // SREF &_decode_V_EOF, $0 self.Sref("_decode_V_EOF", 0) // SREF &_decode_V_EOF, $0
@ -663,11 +660,6 @@ var (
_subr_decode_value = new(_ValueDecoder).build() _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 //go:nosplit
func invalid_vtype(vt types.ValueType) { func invalid_vtype(vt types.ValueType) {
throw(fmt.Sprintf("invalid value type: %d", vt)) throw(fmt.Sprintf("invalid value type: %d", vt))

View file

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

View file

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