Skip to content

Commit

Permalink
fix:(ast) panic when calling SortKeys() on raw node (#522)
Browse files Browse the repository at this point in the history
  • Loading branch information
AsterDY authored Sep 6, 2023
1 parent 61ca8ba commit ada8e06
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 4 deletions.
30 changes: 30 additions & 0 deletions ast/encode_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,36 @@ func TestEncodeNode(t *testing.T) {
}
}

type SortableNode struct {
sorted bool
*Node
}

func (j *SortableNode) UnmarshalJSON(data []byte) (error) {
j.Node = new(Node)
return j.Node.UnmarshalJSON(data)
}

func (j *SortableNode) MarshalJSON() ([]byte, error) {
if !j.sorted {
j.Node.SortKeys(true)
j.sorted = true
}
return j.Node.MarshalJSON()
}

func TestMarshalSort(t *testing.T) {
var data = `{"d":3,"a":{"c":1,"b":2}}`
var obj map[string]*SortableNode
require.NoError(t, json.Unmarshal([]byte(data), &obj))
out, err := json.Marshal(obj)
require.NoError(t, err)
require.Equal(t, `{"a":{"b":2,"c":1},"d":3}`, string(out))
out, err = json.Marshal(obj)
require.NoError(t, err)
require.Equal(t, `{"a":{"b":2,"c":1},"d":3}`, string(out))
}

func BenchmarkEncodeRaw_Sonic(b *testing.B) {
data := _TwitterJson
root, e := NewSearcher(data).GetByPath()
Expand Down
7 changes: 4 additions & 3 deletions ast/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ type Node struct {
// UnmarshalJSON is just an adapter to json.Unmarshaler.
// If you want better performance, use Searcher.GetByPath() directly
func (self *Node) UnmarshalJSON(data []byte) (err error) {
*self, err = NewSearcher(string(data)).GetByPath()
return
*self = NewRaw(string(data))
return self.Check()
}

/** Node Type Accessor **/
Expand Down Expand Up @@ -857,7 +857,8 @@ func (self *Node) unsafeMap() (*linkedPairs, error) {
// SortKeys sorts children of a V_OBJECT node in ascending key-order.
// If recurse is true, it recursively sorts children's children as long as a V_OBJECT node is found.
func (self *Node) SortKeys(recurse bool) error {
if err := self.Check(); err != nil {
// check raw node first
if err := self.checkRaw(); err != nil {
return err
}
if self.itype() == types.V_OBJECT {
Expand Down
1 change: 0 additions & 1 deletion internal/decoder/asm_stubs_amd64_go121.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,6 @@ func (self *_Assembler) WriteRecNotAX(i int, ptr obj.Addr, rec obj.Addr, saveDI
self.Emit("MOVQ", ptr, jit.Ptr(_R11, 0))
self.Emit("MOVQ", rec, _AX)
self.Emit("MOVQ", _AX, jit.Ptr(_R11, 8))
self.load(_R11)
if saveAX {
self.load(_AX, _R11)
} else {
Expand Down

0 comments on commit ada8e06

Please sign in to comment.