Skip to content

Commit

Permalink
validate raw json
Browse files Browse the repository at this point in the history
  • Loading branch information
AsterDY committed Jan 14, 2024
1 parent 73ae242 commit 7687283
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 113 deletions.
24 changes: 0 additions & 24 deletions ast/api_amd64.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,27 +131,3 @@ func (self *Parser) getByPath(path ...interface{}) (int, types.ParsingError) {
}
return start, 0
}

func (self *Searcher) GetByPath(path ...interface{}) (Node, error) {
var err types.ParsingError
var start int

self.parser.p = 0
start, err = self.parser.getByPath(path...)
if err != 0 {
// for compatibility with old version
if err == types.ERR_NOT_FOUND {
return Node{}, ErrNotExist
}
if err == types.ERR_UNSUPPORT_TYPE {
panic("path must be either int(>=0) or string")
}
return Node{}, self.parser.syntaxError(err)
}

t := switchRawType(self.parser.s[start])
if t == _V_NONE {
return Node{}, self.parser.ExportError(err)
}
return newRawNode(self.parser.s[start:self.parser.p], t), nil
}
26 changes: 0 additions & 26 deletions ast/api_compat.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ package ast
import (
`encoding/base64`
`encoding/json`
`fmt`

`github.com/bytedance/sonic/internal/native/types`
`github.com/bytedance/sonic/internal/rt`
Expand Down Expand Up @@ -88,31 +87,6 @@ func (self *Node) encodeInterface(buf *[]byte) error {
return nil
}

func (self *Searcher) GetByPath(path ...interface{}) (Node, error) {
self.parser.p = 0

start, err := self.parser.getByPath(path...)
if err != 0 {
return Node{}, err
}

if _, err = self.parser.skip(); err != 0 {
return Node{}, self.parser.ExportError(err)
}

ns := len(self.parser.s)
if self.parser.p > ns || start >= ns || start>=self.parser.p {
return Node{}, fmt.Errorf("skip %d char out of json boundary", start)
}

t := switchRawType(self.parser.s[start])
if t == _V_NONE {
return Node{}, self.parser.ExportError(err)
}

return newRawNode(self.parser.s[start:self.parser.p], t), nil
}

func (self *Parser) getByPath(path ...interface{}) (int, types.ParsingError) {
for _, p := range path {
if idx, ok := p.(int); ok && idx >= 0 {
Expand Down
92 changes: 49 additions & 43 deletions ast/raw.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,23 @@ import (
"github.com/bytedance/sonic/internal/rt"
)

// RawNode represents a raw json value or error
type RawNode struct {
// Value represents a raw json value or error
type Value struct {
t int
js string
}

func NewRawNode(js string) RawNode {
s := NewParser(js).lspace(0)
if s > len(js) {
return errRawNode(types.ERR_EOF)
func NewValue(js string) Value {
p := NewParser(js)
s, e := p.skip()
if e != 0 {
return errRawNode(p.ExportError(e))
}
return rawNode(js[s:])
return rawNode(js[s:p.p])
}

func rawNode(js string) RawNode {
return RawNode{
func rawNode(js string) Value {
return Value{
t: int(switchRawType(js[0])),
js: js,
}
Expand All @@ -33,35 +34,36 @@ func rawNode(js string) RawNode {
// Type returns json type represented by the node
// It will be one of belows:
// V_NONE = 0 (empty node)
// V_ERROR = 1 (something wrong)
// V_NULL = 2 (json value `null`)
// V_TRUE = 3 (json value `true`)
// V_FALSE = 4 (json value `false`)
// V_ARRAY = 5 (json value array)
// V_OBJECT = 6 (json value object)
// V_STRING = 7 (json value string)
// V_NUMBER = 33 (json value number )
func (self RawNode) Type() int {
func (self Value) Type() int {
return self.t
}

func (self RawNode) Exists() bool {
func (self Value) Exists() bool {
return self.t != 0 && self.t != V_ERROR
}

func (self RawNode) itype() types.ValueType {
func (self Value) itype() types.ValueType {
return types.ValueType(self.t)
}

// Error returns error message if the node is invalid
func (self RawNode) Error() string {
func (self Value) Error() string {
if self.t == V_ERROR {
return self.js
}
return ""
}

// Check checks if the node itself is valid, and return
func (self RawNode) Check() error {
func (self Value) Check() error {
if self.t == V_ERROR {
return errors.New(self.js)
}
Expand All @@ -71,7 +73,7 @@ func (self RawNode) Check() error {

// GetByPath load given path on demands,
// which only ensure nodes before this path got parsed
func (self RawNode) GetByPath(path ...interface{}) RawNode {
func (self Value) GetByPath(path ...interface{}) Value {
if self.Check() != nil {
return self
}
Expand All @@ -83,13 +85,13 @@ func (self RawNode) GetByPath(path ...interface{}) RawNode {
return rawNode(self.js[s:p.p])
}

func errRawNode(err error) RawNode {
return RawNode{t: V_ERROR, js: err.Error()}
func errRawNode(err error) Value {
return Value{t: V_ERROR, js: err.Error()}
}


// Get loads given key of an object node on demands
func (self RawNode) Get(key string) RawNode {
func (self Value) Get(key string) Value {
if self.Check() != nil {
return self
}
Expand All @@ -101,7 +103,8 @@ func (self RawNode) Get(key string) RawNode {
return rawNode(self.js[s:p.p])
}

func (self *RawNode) Set(key string, val RawNode) (bool, error) {
// Set sets the node of given key under self, and reports if the key has existed.
func (self *Value) Set(key string, val Value) (bool, error) {
if val.Check() != nil {
return false, val
}
Expand Down Expand Up @@ -174,7 +177,8 @@ func (self *RawNode) Set(key string, val RawNode) (bool, error) {
return exist, nil
}

func (self *RawNode) Unset(key string) (bool, error) {
// Unset REMOVE the node of given key under object parent, and reports if the key has existed.
func (self *Value) Unset(key string) (bool, error) {
if self.Check() != nil {
return false, self
}
Expand Down Expand Up @@ -230,7 +234,8 @@ func (self *RawNode) Unset(key string) (bool, error) {
return true, nil
}

func (self *RawNode) SetByIndex(id int, val RawNode) (bool, error) {
// SetByIndex sets the node of given index, and reports if the key has existed.
func (self *Value) SetByIndex(id int, val Value) (bool, error) {
if val.Check() != nil {
return false, val
}
Expand Down Expand Up @@ -284,7 +289,8 @@ func (self *RawNode) SetByIndex(id int, val RawNode) (bool, error) {
return exist, nil
}

func (self *RawNode) UnsetByIndex(id int) (bool, error) {
// UnsetByIndex REOMVE the node of given index.
func (self *Value) UnsetByIndex(id int) (bool, error) {
if self.Check() != nil {
return false, self
}
Expand Down Expand Up @@ -320,7 +326,7 @@ func (self *RawNode) UnsetByIndex(id int) (bool, error) {
}

// Index indexies node at given idx
func (self RawNode) Index(idx int) RawNode {
func (self Value) Index(idx int) Value {
if self.Check() != nil {
return self
}
Expand All @@ -332,12 +338,12 @@ func (self RawNode) Index(idx int) RawNode {
return rawNode(self.js[s:p.p])
}

func (self RawNode) str() string {
func (self Value) str() string {
return self.js[1:len(self.js)-1]
}

// Raw returns json representation of the node
func (self RawNode) Raw() (string, error) {
func (self Value) Raw() (string, error) {
if e := self.Check(); e != nil {
return "", e
}
Expand All @@ -346,7 +352,7 @@ func (self RawNode) Raw() (string, error) {

// Bool returns bool value represented by this node,
// including types.V_TRUE|V_FALSE|V_NUMBER|V_STRING|V_ANY|V_NULL
func (self RawNode) Bool() (bool, error) {
func (self Value) Bool() (bool, error) {
if e := self.Check(); e != nil {
return false, e
}
Expand All @@ -367,7 +373,7 @@ func (self RawNode) Bool() (bool, error) {

// Int64 casts the node to int64 value,
// including V_NUMBER|V_TRUE|V_FALSE|V_STRING
func (self RawNode) Int64() (int64, error) {
func (self Value) Int64() (int64, error) {
if e := self.Check(); e != nil {
return 0, e
}
Expand All @@ -388,7 +394,7 @@ func (self RawNode) Int64() (int64, error) {

// Float64 cast node to float64,
// including V_NUMBER|V_TRUE|V_FALSE|V_ANY|V_STRING|V_NULL
func (self RawNode) Float64() (float64, error) {
func (self Value) Float64() (float64, error) {
if e := self.Check(); e != nil {
return 0, e
}
Expand All @@ -409,7 +415,7 @@ func (self RawNode) Float64() (float64, error) {

// Number casts node to float64,
// including V_NUMBER|V_TRUE|V_FALSE|V_ANY|V_STRING|V_NULL,
func (self RawNode) Number() (json.Number, error) {
func (self Value) Number() (json.Number, error) {
if e := self.Check(); e != nil {
return "", e
}
Expand All @@ -430,7 +436,7 @@ func (self RawNode) Number() (json.Number, error) {

// String cast node to string,
// including V_NUMBER|V_TRUE|V_FALSE|V_ANY|V_STRING|V_NULL
func (self RawNode) String() (string, error) {
func (self Value) String() (string, error) {
if e := self.Check(); e != nil {
return "", e
}
Expand All @@ -456,40 +462,40 @@ func (self RawNode) String() (string, error) {

// ArrayUseNode copys both parsed and non-parsed chidren nodes,
// and indexes them by original order
func (self RawNode) ArrayUseNode() (ret []RawNode, err error) {
func (self Value) ArrayUseNode() (ret []Value, err error) {
if self.t != V_ARRAY {
return nil, ErrUnsupportType
}
ret = make([]RawNode, 0, _DEFAULT_NODE_CAP)
err = self.ForEachElem(func(i int, node RawNode) bool {
ret = make([]Value, 0, _DEFAULT_NODE_CAP)
err = self.ForEachElem(func(i int, node Value) bool {
ret = append(ret, node)
return true
})
return ret, err
}

// Array loads all indexes of an array node
func (self RawNode) Array() (ret []interface{}, err error) {
func (self Value) Array() (ret []interface{}, err error) {
node := NewRaw(self.js)
return node.Array()
}

// ObjectUseNode scans both parsed and non-parsed chidren nodes,
// and map them by their keys
func (self RawNode) MapUseNode() (ret []RawPair, err error) {
func (self Value) MapUseNode() (ret []RawPair, err error) {
if self.t != V_OBJECT {
return nil, ErrUnsupportType
}
ret = make([]RawPair, 0, _DEFAULT_NODE_CAP)
err = self.ForEachKV(func(key string, node RawNode) bool {
err = self.ForEachKV(func(key string, node Value) bool {
ret = append(ret, RawPair{key, node})
return true
})
return ret, err
}

// Map loads all keys of an object node
func (self RawNode) Map() (ret map[string]interface{}, err error) {
func (self Value) Map() (ret map[string]interface{}, err error) {
if self.t != V_OBJECT {
return nil, ErrUnsupportType
}
Expand All @@ -500,7 +506,7 @@ func (self RawNode) Map() (ret map[string]interface{}, err error) {
// Interface loads all children under all pathes from this node,
// and converts itself as generic type.
// WARN: all numberic nodes are casted to float64
func (self RawNode) Interface() (interface{}, error) {
func (self Value) Interface() (interface{}, error) {
if e := self.Check(); e != nil {
return nil, e
}
Expand All @@ -526,7 +532,7 @@ func (self RawNode) Interface() (interface{}, error) {


// ForEach scans one V_OBJECT node's children from JSON head to tail
func (self RawNode) ForEachKV(sc func(key string, node RawNode) bool) error {
func (self Value) ForEachKV(sc func(key string, node Value) bool) error {
if e := self.Check(); e != nil {
return e
}
Expand Down Expand Up @@ -566,7 +572,7 @@ func (self RawNode) ForEachKV(sc func(key string, node RawNode) bool) error {
}

// ForEach scans one V_OBJECT node's children from JSON head to tail
func (self RawNode) ForEachElem(sc func(i int, node RawNode) bool) error {
func (self Value) ForEachElem(sc func(i int, node Value) bool) error {
if e := self.Check(); e != nil {
return e
}
Expand Down Expand Up @@ -604,11 +610,11 @@ func (self RawNode) ForEachElem(sc func(i int, node RawNode) bool) error {
// RawPair is a pair of key and value (RawNode)
type RawPair struct {
Key string
Value RawNode
Value Value
}

// GetRawByPath
func (self Searcher) GetRawByPath(path ...interface{}) (RawNode, error) {
func (self Searcher) GetRawByPath(path ...interface{}) (Value, error) {
if self.parser.s == "" {
err := errors.New("empty input")
return errRawNode(err), err
Expand All @@ -626,5 +632,5 @@ func (self Searcher) GetRawByPath(path ...interface{}) (RawNode, error) {
e := self.parser.ExportError(err)
return errRawNode(e), e
}
return RawNode{int(t), self.parser.s[s:self.parser.p]}, nil
return Value{int(t), self.parser.s[s:self.parser.p]}, nil
}

Check failure on line 636 in ast/raw.go

View workflow job for this annotation

GitHub Actions / build (1.20.x)

syntax error: unexpected var after top level declaration
Loading

0 comments on commit 7687283

Please sign in to comment.