mirror of
https://github.com/ii64/sonic.git
synced 2026-06-22 17:36:48 +08:00
fix:(native) StreamDecoder returns error when run out of buffer while skiping value (#267)
* fix:(native) StreamDecoder return error when run out of input buffer while skiping value * refactor
This commit is contained in:
parent
34026b9c65
commit
2eae594741
8 changed files with 10077 additions and 9905 deletions
|
|
@ -94,11 +94,12 @@ read_more:
|
||||||
}
|
}
|
||||||
first = false
|
first = false
|
||||||
|
|
||||||
if len(buf) > 0 {
|
l := len(buf)
|
||||||
|
if l > 0 {
|
||||||
self.Decoder.Reset(string(buf))
|
self.Decoder.Reset(string(buf))
|
||||||
err = self.Decoder.Decode(val)
|
err = self.Decoder.Decode(val)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if ee, ok := err.(SyntaxError); repeat && ok && ee.Code == types.ERR_EOF {
|
if repeat && repeatable(err) {
|
||||||
goto read_more
|
goto read_more
|
||||||
}
|
}
|
||||||
self.err = err
|
self.err = err
|
||||||
|
|
@ -109,7 +110,7 @@ read_more:
|
||||||
self.scanp = 0
|
self.scanp = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(buf) > p {
|
if l > p {
|
||||||
// remain undecoded bytes, so copy them into self.buf
|
// remain undecoded bytes, so copy them into self.buf
|
||||||
self.buf = append(self.buf[:0], buf[p:]...)
|
self.buf = append(self.buf[:0], buf[p:]...)
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -124,6 +125,13 @@ read_more:
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func repeatable(err error) bool {
|
||||||
|
if ee, ok := err.(SyntaxError); ok && ee.Code == types.ERR_EOF {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// InputOffset returns the input stream byte offset of the current decoder position.
|
// InputOffset returns the input stream byte offset of the current decoder position.
|
||||||
// The offset gives the location of the end of the most recently returned token and the beginning of the next token.
|
// The offset gives the location of the end of the most recently returned token and the beginning of the next token.
|
||||||
func (self *StreamDecoder) InputOffset() int64 {
|
func (self *StreamDecoder) InputOffset() int64 {
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@
|
||||||
package decoder
|
package decoder
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
`bytes`
|
||||||
`encoding/json`
|
`encoding/json`
|
||||||
`io`
|
`io`
|
||||||
`io/ioutil`
|
`io/ioutil`
|
||||||
|
|
@ -35,6 +36,39 @@ var (
|
||||||
strings.Repeat("2",1024)+`"} b {}`
|
strings.Repeat("2",1024)+`"} b {}`
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func TestStreamError(t *testing.T) {
|
||||||
|
var qs = []string{
|
||||||
|
`{`+strings.Repeat(" ", 1024)+`"`,
|
||||||
|
`{`+strings.Repeat(" ", 1024)+`"}`,
|
||||||
|
`{`+strings.Repeat(" ", 1024)+`""}`,
|
||||||
|
`{`+strings.Repeat(" ", 1024)+`"":}`,
|
||||||
|
`{`+strings.Repeat(" ", 1024)+`"":]`,
|
||||||
|
`{`+strings.Repeat(" ", 1024)+`"":1x`,
|
||||||
|
`{`+strings.Repeat(" ", 1024)+`"":1x}`,
|
||||||
|
`{`+strings.Repeat(" ", 1024)+`"":1x]`,
|
||||||
|
`{`+strings.Repeat(" ", 1024)+`"":t`,
|
||||||
|
`{`+strings.Repeat(" ", 1024)+`"":t}`,
|
||||||
|
`{`+strings.Repeat(" ", 1024)+`"":true]`,
|
||||||
|
`{`+strings.Repeat(" ", 1024)+`"":f`,
|
||||||
|
`{`+strings.Repeat(" ", 1024)+`"":f}`,
|
||||||
|
`{`+strings.Repeat(" ", 1024)+`"":false]`,
|
||||||
|
`{`+strings.Repeat(" ", 1024)+`"":n`,
|
||||||
|
`{`+strings.Repeat(" ", 1024)+`"":n}`,
|
||||||
|
`{`+strings.Repeat(" ", 1024)+`"":null]`,
|
||||||
|
`{`+strings.Repeat(" ", 1024)+`"":"`,
|
||||||
|
`{`+strings.Repeat(" ", 1024)+`"":"a`,
|
||||||
|
`{`+strings.Repeat(" ", 1024)+`"":"a}`,
|
||||||
|
`{`+strings.Repeat(" ", 1024)+`"":"a"`,
|
||||||
|
`{`+strings.Repeat(" ", 1024)+`"":"a"]`,
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, q := range qs {
|
||||||
|
var qq = []byte(q[:1024]+strings.Repeat(" ", i*100)+q[1024:])
|
||||||
|
var obj interface{}
|
||||||
|
require.NotNil(t, NewStreamDecoder(bytes.NewReader(qq)).Decode(&obj))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestDecodeEmpty(t *testing.T) {
|
func TestDecodeEmpty(t *testing.T) {
|
||||||
var str = ``
|
var str = ``
|
||||||
var r1 = strings.NewReader(str)
|
var r1 = strings.NewReader(str)
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -9,45 +9,45 @@ package avx
|
||||||
func __native_entry__() uintptr
|
func __native_entry__() uintptr
|
||||||
|
|
||||||
var (
|
var (
|
||||||
_subr__f64toa = __native_entry__() + 570
|
_subr__f64toa = __native_entry__() + 630
|
||||||
_subr__html_escape = __native_entry__() + 8834
|
_subr__html_escape = __native_entry__() + 8581
|
||||||
_subr__i64toa = __native_entry__() + 3653
|
_subr__i64toa = __native_entry__() + 3642
|
||||||
_subr__lspace = __native_entry__() + 251
|
_subr__lspace = __native_entry__() + 301
|
||||||
_subr__lzero = __native_entry__() + 13
|
_subr__lzero = __native_entry__() + 13
|
||||||
_subr__quote = __native_entry__() + 4970
|
_subr__quote = __native_entry__() + 4955
|
||||||
_subr__skip_array = __native_entry__() + 18226
|
_subr__skip_array = __native_entry__() + 17819
|
||||||
_subr__skip_number = __native_entry__() + 21165
|
_subr__skip_number = __native_entry__() + 20937
|
||||||
_subr__skip_object = __native_entry__() + 18263
|
_subr__skip_object = __native_entry__() + 17856
|
||||||
_subr__skip_one = __native_entry__() + 16378
|
_subr__skip_one = __native_entry__() + 16120
|
||||||
_subr__u64toa = __native_entry__() + 3748
|
_subr__u64toa = __native_entry__() + 3735
|
||||||
_subr__unquote = __native_entry__() + 6540
|
_subr__unquote = __native_entry__() + 6426
|
||||||
_subr__validate_one = __native_entry__() + 21282
|
_subr__validate_one = __native_entry__() + 21054
|
||||||
_subr__value = __native_entry__() + 11437
|
_subr__value = __native_entry__() + 11301
|
||||||
_subr__vnumber = __native_entry__() + 14392
|
_subr__vnumber = __native_entry__() + 14278
|
||||||
_subr__vsigned = __native_entry__() + 15822
|
_subr__vsigned = __native_entry__() + 15592
|
||||||
_subr__vstring = __native_entry__() + 13345
|
_subr__vstring = __native_entry__() + 13243
|
||||||
_subr__vunsigned = __native_entry__() + 16102
|
_subr__vunsigned = __native_entry__() + 15851
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
_stack__f64toa = 120
|
_stack__f64toa = 120
|
||||||
_stack__html_escape = 64
|
_stack__html_escape = 72
|
||||||
_stack__i64toa = 24
|
_stack__i64toa = 24
|
||||||
_stack__lspace = 8
|
_stack__lspace = 8
|
||||||
_stack__lzero = 8
|
_stack__lzero = 8
|
||||||
_stack__quote = 80
|
_stack__quote = 56
|
||||||
_stack__skip_array = 152
|
_stack__skip_array = 144
|
||||||
_stack__skip_number = 88
|
_stack__skip_number = 96
|
||||||
_stack__skip_object = 152
|
_stack__skip_object = 144
|
||||||
_stack__skip_one = 152
|
_stack__skip_one = 144
|
||||||
_stack__u64toa = 8
|
_stack__u64toa = 8
|
||||||
_stack__unquote = 80
|
_stack__unquote = 88
|
||||||
_stack__validate_one = 152
|
_stack__validate_one = 144
|
||||||
_stack__value = 424
|
_stack__value = 416
|
||||||
_stack__vnumber = 320
|
_stack__vnumber = 312
|
||||||
_stack__vsigned = 16
|
_stack__vsigned = 16
|
||||||
_stack__vstring = 120
|
_stack__vstring = 128
|
||||||
_stack__vunsigned = 16
|
_stack__vunsigned = 8
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -9,24 +9,24 @@ package avx2
|
||||||
func __native_entry__() uintptr
|
func __native_entry__() uintptr
|
||||||
|
|
||||||
var (
|
var (
|
||||||
_subr__f64toa = __native_entry__() + 825
|
_subr__f64toa = __native_entry__() + 903
|
||||||
_subr__html_escape = __native_entry__() + 10493
|
_subr__html_escape = __native_entry__() + 10249
|
||||||
_subr__i64toa = __native_entry__() + 3908
|
_subr__i64toa = __native_entry__() + 3915
|
||||||
_subr__lspace = __native_entry__() + 379
|
_subr__lspace = __native_entry__() + 429
|
||||||
_subr__lzero = __native_entry__() + 13
|
_subr__lzero = __native_entry__() + 13
|
||||||
_subr__quote = __native_entry__() + 5325
|
_subr__quote = __native_entry__() + 5328
|
||||||
_subr__skip_array = __native_entry__() + 21311
|
_subr__skip_array = __native_entry__() + 21867
|
||||||
_subr__skip_number = __native_entry__() + 24831
|
_subr__skip_number = __native_entry__() + 25515
|
||||||
_subr__skip_object = __native_entry__() + 21348
|
_subr__skip_object = __native_entry__() + 21904
|
||||||
_subr__skip_one = __native_entry__() + 19468
|
_subr__skip_one = __native_entry__() + 19172
|
||||||
_subr__u64toa = __native_entry__() + 4003
|
_subr__u64toa = __native_entry__() + 4008
|
||||||
_subr__unquote = __native_entry__() + 7998
|
_subr__unquote = __native_entry__() + 7794
|
||||||
_subr__validate_one = __native_entry__() + 24948
|
_subr__validate_one = __native_entry__() + 25632
|
||||||
_subr__value = __native_entry__() + 14390
|
_subr__value = __native_entry__() + 14495
|
||||||
_subr__vnumber = __native_entry__() + 17482
|
_subr__vnumber = __native_entry__() + 17330
|
||||||
_subr__vsigned = __native_entry__() + 18912
|
_subr__vsigned = __native_entry__() + 18644
|
||||||
_subr__vstring = __native_entry__() + 16575
|
_subr__vstring = __native_entry__() + 16453
|
||||||
_subr__vunsigned = __native_entry__() + 19192
|
_subr__vunsigned = __native_entry__() + 18903
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
@ -35,19 +35,19 @@ const (
|
||||||
_stack__i64toa = 24
|
_stack__i64toa = 24
|
||||||
_stack__lspace = 8
|
_stack__lspace = 8
|
||||||
_stack__lzero = 8
|
_stack__lzero = 8
|
||||||
_stack__quote = 72
|
_stack__quote = 56
|
||||||
_stack__skip_array = 160
|
_stack__skip_array = 152
|
||||||
_stack__skip_number = 96
|
_stack__skip_number = 96
|
||||||
_stack__skip_object = 160
|
_stack__skip_object = 152
|
||||||
_stack__skip_one = 160
|
_stack__skip_one = 152
|
||||||
_stack__u64toa = 8
|
_stack__u64toa = 8
|
||||||
_stack__unquote = 72
|
_stack__unquote = 72
|
||||||
_stack__validate_one = 160
|
_stack__validate_one = 152
|
||||||
_stack__value = 424
|
_stack__value = 408
|
||||||
_stack__vnumber = 320
|
_stack__vnumber = 312
|
||||||
_stack__vsigned = 16
|
_stack__vsigned = 16
|
||||||
_stack__vstring = 112
|
_stack__vstring = 112
|
||||||
_stack__vunsigned = 16
|
_stack__vunsigned = 8
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
|
||||||
49
issue_test/issue263_test.go
Normal file
49
issue_test/issue263_test.go
Normal file
|
|
@ -0,0 +1,49 @@
|
||||||
|
package issue_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
`bytes`
|
||||||
|
`strings`
|
||||||
|
`testing`
|
||||||
|
|
||||||
|
`github.com/bytedance/sonic/decoder`
|
||||||
|
`github.com/stretchr/testify/require`
|
||||||
|
)
|
||||||
|
|
||||||
|
type Response struct {
|
||||||
|
Menu Menu `json:"menu"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Menu struct {
|
||||||
|
Items []*Item `json:"items"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Item struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *Item) UnmarshalJSON(buf []byte) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIssue263(t *testing.T) {
|
||||||
|
q := `{
|
||||||
|
"menu": {
|
||||||
|
"items": [
|
||||||
|
{`+strings.Repeat(" ", 1024)+`}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}`
|
||||||
|
|
||||||
|
var response Response
|
||||||
|
require.Nil(t, decoder.NewStreamDecoder(bytes.NewReader([]byte(q))).Decode(&response))
|
||||||
|
|
||||||
|
q = `{
|
||||||
|
"menu": {
|
||||||
|
"items": [
|
||||||
|
{"a":"`+strings.Repeat("b", 2048)+`"}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}`
|
||||||
|
|
||||||
|
require.Nil(t, decoder.NewStreamDecoder(bytes.NewReader([]byte(q))).Decode(&response))
|
||||||
|
}
|
||||||
|
|
@ -1003,6 +1003,9 @@ static inline long fsm_exec(StateMachine *self, const GoString *src, long *p, in
|
||||||
/* run until no more nested values */
|
/* run until no more nested values */
|
||||||
while (self->sp) {
|
while (self->sp) {
|
||||||
ch = advance_ns(src, p);
|
ch = advance_ns(src, p);
|
||||||
|
if (ch == 0) {
|
||||||
|
return -ERR_EOF;
|
||||||
|
}
|
||||||
vt = self->vt[self->sp - 1];
|
vt = self->vt[self->sp - 1];
|
||||||
|
|
||||||
/* set the start address if any */
|
/* set the start address if any */
|
||||||
|
|
@ -1115,7 +1118,6 @@ static inline long fsm_exec(StateMachine *self, const GoString *src, long *p, in
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 0 : return -ERR_EOF;
|
|
||||||
default : return -ERR_INVAL;
|
default : return -ERR_INVAL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue