Skip to content

Commit

Permalink
fix:(native) StreamDecoder return error when run out of input buffer …
Browse files Browse the repository at this point in the history
…while skiping value
  • Loading branch information
AsterDY committed Jul 22, 2022
1 parent 755c025 commit a225b81
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 3 deletions.
16 changes: 13 additions & 3 deletions decoder/stream.go
Expand Up @@ -94,11 +94,12 @@ read_more:
}
first = false

if len(buf) > 0 {
l := len(buf)
if l > 0 {
self.Decoder.Reset(string(buf))
err = self.Decoder.Decode(val)
if err != nil {
if ee, ok := err.(SyntaxError); repeat && ok && ee.Code == types.ERR_EOF {
if repeat && repeatable(err, l) {
goto read_more
}
self.err = err
Expand All @@ -109,7 +110,7 @@ read_more:
self.scanp = 0
}

if len(buf) > p {
if l > p {
// remain undecoded bytes, so copy them into self.buf
self.buf = append(self.buf[:0], buf[p:]...)
} else {
Expand All @@ -124,6 +125,15 @@ read_more:
return err
}

func repeatable(err error, l int) bool {
if ee, ok := err.(SyntaxError); ok {
if ee.Code == types.ERR_EOF || ee.Code == types.ERR_INVALID_CHAR && ee.Pos >= l {
return true
}
}
return false
}

// 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.
func (self *StreamDecoder) InputOffset() int64 {
Expand Down
91 changes: 91 additions & 0 deletions issue_test/issue263_test.go
@@ -0,0 +1,91 @@
package issue_test

import (
`bytes`
`testing`

`github.com/bytedance/sonic/ast`
`github.com/bytedance/sonic/decoder`
`github.com/davecgh/go-spew/spew`
)


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 TestName(t *testing.T) {
q := `{
"menu": {
"items": [{
"id": "carrotcake",
"name": {
"en": "CarrotCake Name"
},
"operational_name": "carrotCake-op",
"description": null,
"plu": "carrotCake45",
"ian": "carrotCake_ian_45",
"external_data": "",
"image": {
"url": "http://127.0.0.1:50207/image7.jpg"
},
"tax_rate": "20",
"modifier_ids": [
"add-hot-drinks-mod"
],
"contains_alcohol": false,
"max_quantity": null,
"is_eligible_for_substitution": true,
"is_eligible_as_replacement": true
},
{
"id": "cheeseburger",
"name": {
"en": "Cheeseburger Name"
},
"operational_name": "cheeseburger-op",
"description": null,
"plu": "cheeseburger40",
"ian": "cheeseburger_ian_40",
"external_data": "",
"image": {
"url": "http://127.0.0.1:50207/image1.jpg"
},
"tax_rate": "20",
"modifier_ids": [
"add-drinks-mod"
],
"contains_alcohol": false,
"max_quantity": null,
"is_eligible_for_substitution": true,
"is_eligible_as_replacement": true
}
]
}
}`

n, err := ast.NewSearcher(q).GetByPath("menu", "items", 1)
if err != nil {
t.Fatal(err)
}
spew.Dump(n.Interface())

var response Response
err = decoder.NewStreamDecoder(bytes.NewReader([]byte(q))).Decode(&response)
if err != nil {
t.Fatal(err)
}

}

0 comments on commit a225b81

Please sign in to comment.