diff --git a/decode_test.go b/decode_test.go index f56806f..204babf 100644 --- a/decode_test.go +++ b/decode_test.go @@ -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{} { diff --git a/decoder/generic_amd64.go b/decoder/generic_amd64.go index 70fd0c5..7428381 100644 --- a/decoder/generic_amd64.go +++ b/decoder/generic_amd64.go @@ -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)) diff --git a/decoder/pools.go b/decoder/pools.go index 237c609..f054b68 100644 --- a/decoder/pools.go +++ b/decoder/pools.go @@ -27,7 +27,7 @@ import ( const ( _MinSlice = 16 - _MaxStack = 262144 // 256k slots + _MaxStack = 65536 // 64k slots ) const ( diff --git a/issue27_test.go b/issue27_test.go index 17e7e83..afcf267 100644 --- a/issue27_test.go +++ b/issue27_test.go @@ -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() }