summaryrefslogtreecommitdiff
path: root/vendor/github.com/bytedance/sonic/ast
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/bytedance/sonic/ast')
-rw-r--r--vendor/github.com/bytedance/sonic/ast/api.go19
-rw-r--r--vendor/github.com/bytedance/sonic/ast/api_compat.go91
-rw-r--r--vendor/github.com/bytedance/sonic/ast/b64_amd64.go2
-rw-r--r--vendor/github.com/bytedance/sonic/ast/decode.go33
-rw-r--r--vendor/github.com/bytedance/sonic/ast/node.go22
-rw-r--r--vendor/github.com/bytedance/sonic/ast/parser.go5
-rw-r--r--vendor/github.com/bytedance/sonic/ast/search.go66
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
+}