2
0
Fork 0
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:
Yi Duan 2022-07-25 15:17:52 +08:00 committed by GitHub
parent 34026b9c65
commit 2eae594741
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 10077 additions and 9905 deletions

View file

@ -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 {

View file

@ -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

View file

@ -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

View file

@ -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 (

View 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))
}

View file

@ -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;
} }
} }