diff options
Diffstat (limited to 'vendor/github.com/bytedance/sonic/ast')
-rw-r--r-- | vendor/github.com/bytedance/sonic/ast/api.go | 19 | ||||
-rw-r--r-- | vendor/github.com/bytedance/sonic/ast/api_compat.go | 91 | ||||
-rw-r--r-- | vendor/github.com/bytedance/sonic/ast/b64_amd64.go | 2 | ||||
-rw-r--r-- | vendor/github.com/bytedance/sonic/ast/decode.go | 33 | ||||
-rw-r--r-- | vendor/github.com/bytedance/sonic/ast/node.go | 22 | ||||
-rw-r--r-- | vendor/github.com/bytedance/sonic/ast/parser.go | 5 | ||||
-rw-r--r-- | vendor/github.com/bytedance/sonic/ast/search.go | 66 |
7 files changed, 177 insertions, 61 deletions
diff --git a/vendor/github.com/bytedance/sonic/ast/api.go b/vendor/github.com/bytedance/sonic/ast/api.go index 373d62a9f..316a62a9d 100644 --- a/vendor/github.com/bytedance/sonic/ast/api.go +++ b/vendor/github.com/bytedance/sonic/ast/api.go @@ -1,3 +1,4 @@ +//go:build (amd64 && go1.16 && !go1.23) || (arm64 && go1.20 && !go1.23) // +build amd64,go1.16,!go1.23 arm64,go1.20,!go1.23 /* @@ -27,6 +28,7 @@ import ( `github.com/bytedance/sonic/internal/native/types` `github.com/bytedance/sonic/internal/rt` uq `github.com/bytedance/sonic/unquote` + `github.com/bytedance/sonic/utf8` ) var typeByte = rt.UnpackEface(byte(0)).Type @@ -101,7 +103,7 @@ func (self *Parser) skip() (int, types.ParsingError) { func (self *Node) encodeInterface(buf *[]byte) error { //WARN: NOT compatible with json.Encoder - return encoder.EncodeInto(buf, self.packAny(), 0) + return encoder.EncodeInto(buf, self.packAny(), encoder.NoEncoderNewline) } func (self *Parser) skipFast() (int, types.ParsingError) { @@ -112,13 +114,22 @@ func (self *Parser) skipFast() (int, types.ParsingError) { return start, 0 } -func (self *Parser) getByPath(path ...interface{}) (int, types.ParsingError) { - fsm := types.NewStateMachine() +func (self *Parser) getByPath(validate bool, path ...interface{}) (int, types.ParsingError) { + var fsm *types.StateMachine + if validate { + fsm = types.NewStateMachine() + } start := native.GetByPath(&self.s, &self.p, &path, fsm) - types.FreeStateMachine(fsm) + if validate { + types.FreeStateMachine(fsm) + } runtime.KeepAlive(path) if start < 0 { return self.p, types.ParsingError(-start) } return start, 0 } + +func validate_utf8(str string) bool { + return utf8.ValidateString(str) +} diff --git a/vendor/github.com/bytedance/sonic/ast/api_compat.go b/vendor/github.com/bytedance/sonic/ast/api_compat.go index 2c889fc2a..82d1eacd3 100644 --- a/vendor/github.com/bytedance/sonic/ast/api_compat.go +++ b/vendor/github.com/bytedance/sonic/ast/api_compat.go @@ -19,67 +19,69 @@ package ast import ( - `encoding/json` + `encoding/json` + `unicode/utf8` - `github.com/bytedance/sonic/internal/native/types` - `github.com/bytedance/sonic/internal/rt` + `github.com/bytedance/sonic/internal/native/types` + `github.com/bytedance/sonic/internal/rt` ) func init() { - println("WARNING:(ast) sonic only supports Go1.16~1.22, but your environment is not suitable") + println("WARNING:(ast) sonic only supports Go1.16~1.22, but your environment is not suitable") } func quote(buf *[]byte, val string) { - quoteString(buf, val) + quoteString(buf, val) } +// unquote unescapes a internal JSON string (it doesn't count quotas at the begining and end) func unquote(src string) (string, types.ParsingError) { - sp := rt.IndexChar(src, -1) - out, ok := unquoteBytes(rt.BytesFrom(sp, len(src)+2, len(src)+2)) - if !ok { - return "", types.ERR_INVALID_ESCAPE - } - return rt.Mem2Str(out), 0 + sp := rt.IndexChar(src, -1) + out, ok := unquoteBytes(rt.BytesFrom(sp, len(src)+2, len(src)+2)) + if !ok { + return "", types.ERR_INVALID_ESCAPE + } + return rt.Mem2Str(out), 0 } func (self *Parser) decodeValue() (val types.JsonState) { - e, v := decodeValue(self.s, self.p, self.dbuf == nil) - if e < 0 { - return v - } - self.p = e - return v + e, v := decodeValue(self.s, self.p, self.dbuf == nil) + if e < 0 { + return v + } + self.p = e + return v } func (self *Parser) skip() (int, types.ParsingError) { - e, s := skipValue(self.s, self.p) - if e < 0 { - return self.p, types.ParsingError(-e) - } - self.p = e - return s, 0 + e, s := skipValue(self.s, self.p) + if e < 0 { + return self.p, types.ParsingError(-e) + } + self.p = e + return s, 0 } func (self *Parser) skipFast() (int, types.ParsingError) { - e, s := skipValueFast(self.s, self.p) - if e < 0 { - return self.p, types.ParsingError(-e) - } - self.p = e - return s, 0 + e, s := skipValueFast(self.s, self.p) + if e < 0 { + return self.p, types.ParsingError(-e) + } + self.p = e + return s, 0 } func (self *Node) encodeInterface(buf *[]byte) error { - out, err := json.Marshal(self.packAny()) - if err != nil { - return err - } - *buf = append(*buf, out...) - return nil + out, err := json.Marshal(self.packAny()) + if err != nil { + return err + } + *buf = append(*buf, out...) + return nil } -func (self *Parser) getByPath(path ...interface{}) (int, types.ParsingError) { +func (self *Parser) getByPath(validate bool, path ...interface{}) (int, types.ParsingError) { for _, p := range path { if idx, ok := p.(int); ok && idx >= 0 { if err := self.searchIndex(idx); err != 0 { @@ -93,13 +95,20 @@ func (self *Parser) getByPath(path ...interface{}) (int, types.ParsingError) { panic("path must be either int(>=0) or string") } } - start, e := self.skip() + + var start int + var e types.ParsingError + if validate { + start, e = self.skip() + } else { + start, e = self.skipFast() + } if e != 0 { return self.p, e } - // t := switchRawType(self.s[start]) - // if t == _V_NUMBER { - // self.p = 1 + backward(self.s, self.p-1) - // } return start, 0 } + +func validate_utf8(str string) bool { + return utf8.ValidString(str) +} diff --git a/vendor/github.com/bytedance/sonic/ast/b64_amd64.go b/vendor/github.com/bytedance/sonic/ast/b64_amd64.go index fd3d85e36..3e32b600b 100644 --- a/vendor/github.com/bytedance/sonic/ast/b64_amd64.go +++ b/vendor/github.com/bytedance/sonic/ast/b64_amd64.go @@ -19,7 +19,7 @@ package ast import ( - `github.com/chenzhuoyu/base64x` + `github.com/cloudwego/base64x` ) func decodeBase64(src string) ([]byte, error) { diff --git a/vendor/github.com/bytedance/sonic/ast/decode.go b/vendor/github.com/bytedance/sonic/ast/decode.go index 3e08bfcb2..c521fb5f0 100644 --- a/vendor/github.com/bytedance/sonic/ast/decode.go +++ b/vendor/github.com/bytedance/sonic/ast/decode.go @@ -583,3 +583,36 @@ func skipArray(src string, pos int) (ret int, start int) { pos++ } } + +// DecodeString decodes a JSON string from pos and return golang string. +// - needEsc indicates if to unescaped escaping chars +// - hasEsc tells if the returned string has escaping chars +// - validStr enables validating UTF8 charset +// +func _DecodeString(src string, pos int, needEsc bool, validStr bool) (v string, ret int, hasEsc bool) { + p := NewParserObj(src) + p.p = pos + switch val := p.decodeValue(); val.Vt { + case types.V_STRING: + str := p.s[val.Iv : p.p-1] + if validStr && !validate_utf8(str) { + return "", -int(types.ERR_INVALID_UTF8), false + } + /* fast path: no escape sequence */ + if val.Ep == -1 { + return str, p.p, false + } else if !needEsc { + return str, p.p, true + } + /* unquote the string */ + out, err := unquote(str) + /* check for errors */ + if err != 0 { + return "", -int(err), true + } else { + return out, p.p, true + } + default: + return "", -int(_ERR_UNSUPPORT_TYPE), false + } +} diff --git a/vendor/github.com/bytedance/sonic/ast/node.go b/vendor/github.com/bytedance/sonic/ast/node.go index 9637659b1..ac6d22808 100644 --- a/vendor/github.com/bytedance/sonic/ast/node.go +++ b/vendor/github.com/bytedance/sonic/ast/node.go @@ -852,29 +852,29 @@ func (self *Node) IndexPair(idx int) *Pair { } func (self *Node) indexOrGet(idx int, key string) (*Node, int) { - if err := self.should(types.V_OBJECT, "an object"); err != nil { - return unwrapError(err), idx - } + if err := self.should(types.V_OBJECT, "an object"); err != nil { + return unwrapError(err), idx + } - pr := self.skipIndexPair(idx) - if pr != nil && pr.Key == key { - return &pr.Value, idx - } + pr := self.skipIndexPair(idx) + if pr != nil && pr.Key == key { + return &pr.Value, idx + } - return self.skipKey(key) + return self.skipKey(key) } // IndexOrGet firstly use idx to index a value and check if its key matches // If not, then use the key to search value func (self *Node) IndexOrGet(idx int, key string) *Node { - node, _ := self.indexOrGet(idx, key) - return node + node, _ := self.indexOrGet(idx, key) + return node } // IndexOrGetWithIdx attempts to retrieve a node by index and key, returning the node and its correct index. // If the key does not match at the given index, it searches by key and returns the node with its updated index. func (self *Node) IndexOrGetWithIdx(idx int, key string) (*Node, int) { - return self.indexOrGet(idx, key) + return self.indexOrGet(idx, key) } /** Generic Value Converters **/ diff --git a/vendor/github.com/bytedance/sonic/ast/parser.go b/vendor/github.com/bytedance/sonic/ast/parser.go index 3e5309c19..a1f582623 100644 --- a/vendor/github.com/bytedance/sonic/ast/parser.go +++ b/vendor/github.com/bytedance/sonic/ast/parser.go @@ -653,3 +653,8 @@ func (self *Parser) ExportError(err types.ParsingError) error { Code: err, }.Description()) } + +func backward(src string, i int) int { + for ; i>=0 && isSpace(src[i]); i-- {} + return i +} diff --git a/vendor/github.com/bytedance/sonic/ast/search.go b/vendor/github.com/bytedance/sonic/ast/search.go index 7108e7ea6..a8d1e76f6 100644 --- a/vendor/github.com/bytedance/sonic/ast/search.go +++ b/vendor/github.com/bytedance/sonic/ast/search.go @@ -36,7 +36,7 @@ func NewSearcher(str string) *Searcher { // GetByPathCopy search in depth from top json and returns a **Copied** json node at the path location func (self *Searcher) GetByPathCopy(path ...interface{}) (Node, error) { - return self.getByPath(true, path...) + return self.getByPath(true, true, path...) } // GetByPathNoCopy search in depth from top json and returns a **Referenced** json node at the path location @@ -44,15 +44,15 @@ func (self *Searcher) GetByPathCopy(path ...interface{}) (Node, error) { // WARN: this search directly refer partial json from top json, which has faster speed, // may consumes more memory. func (self *Searcher) GetByPath(path ...interface{}) (Node, error) { - return self.getByPath(false, path...) + return self.getByPath(false, true, path...) } -func (self *Searcher) getByPath(copystring bool, path ...interface{}) (Node, error) { +func (self *Searcher) getByPath(copystring bool, validate bool, path ...interface{}) (Node, error) { var err types.ParsingError var start int self.parser.p = 0 - start, err = self.parser.getByPath(path...) + start, err = self.parser.getByPath(validate, path...) if err != 0 { // for compatibility with old version if err == types.ERR_NOT_FOUND { @@ -78,3 +78,61 @@ func (self *Searcher) getByPath(copystring bool, path ...interface{}) (Node, err } return newRawNode(raw, t), nil } + +// GetByPath searches a path and returns relaction and types of target +func _GetByPath(src string, path ...interface{}) (start int, end int, typ int, err error) { + p := NewParserObj(src) + s, e := p.getByPath(false, path...) + if e != 0 { + // for compatibility with old version + if e == types.ERR_NOT_FOUND { + return -1, -1, 0, ErrNotExist + } + if e == types.ERR_UNSUPPORT_TYPE { + panic("path must be either int(>=0) or string") + } + return -1, -1, 0, p.syntaxError(e) + } + + t := switchRawType(p.s[s]) + if t == _V_NONE { + return -1, -1, 0, ErrNotExist + } + if t == _V_NUMBER { + p.p = 1 + backward(p.s, p.p-1) + } + return s, p.p, int(t), nil +} + +// ValidSyntax check if a json has a valid JSON syntax, +// while not validate UTF-8 charset +func _ValidSyntax(json string) bool { + p := NewParserObj(json) + _, e := p.skip() + if e != 0 { + return false + } + if skipBlank(p.s, p.p) != -int(types.ERR_EOF) { + return false + } + return true +} + +// SkipFast skip a json value in fast-skip algs, +// while not strictly validate JSON syntax and UTF-8 charset. +func _SkipFast(src string, i int) (int, int, error) { + p := NewParserObj(src) + p.p = i + s, e := p.skipFast() + if e != 0 { + return -1, -1, p.ExportError(e) + } + t := switchRawType(p.s[s]) + if t == _V_NONE { + return -1, -1, ErrNotExist + } + if t == _V_NUMBER { + p.p = 1 + backward(p.s, p.p-1) + } + return s, p.p, nil +} |