Skip to content

Commit

Permalink
fix(ast): return error when get from single json value (#373)
Browse files Browse the repository at this point in the history
* fix(ast): return error when get from single json value

* fix: fallback impl of skipstring
  • Loading branch information
liuq19 authored Mar 2, 2023
1 parent 6d60889 commit 10e45e9
Show file tree
Hide file tree
Showing 9 changed files with 21,569 additions and 23,064 deletions.
10 changes: 4 additions & 6 deletions ast/decode.go
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,7 @@ func skipString(src string, pos int) (ret int, ep int) {
sp := uintptr(rt.IndexChar(src, pos))
se := uintptr(rt.IndexChar(src, len(src)))

// not start with quote
if *(*byte)(unsafe.Pointer(sp)) != '"' {
return -int(types.ERR_INVALID_CHAR), -1
}
Expand All @@ -350,16 +351,13 @@ func skipString(src string, pos int) (ret int, ep int) {
}
sp += 1
if c == '"' {
break
return int(uintptr(sp) - uintptr((*rt.GoString)(unsafe.Pointer(&src)).Ptr)), ep
}
}

if sp > se {
return -int(types.ERR_EOF), -1
}

runtime.KeepAlive(src)
return int(uintptr(sp) - uintptr((*rt.GoString)(unsafe.Pointer(&src)).Ptr)), ep
// not found the closed quote until EOF
return -int(types.ERR_EOF), -1
}

//go:nocheckptr
Expand Down
60 changes: 60 additions & 0 deletions ast/search_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,66 @@ func TestSearcher_GetByPath(t *testing.T) {
}
}

type testGetByPath struct {
json string
path []interface{}
value interface{}
ok bool
}

func TestSearcher_GetByPathOk(t *testing.T) {
type Path = []interface{}
const Ok = true
tests := []testGetByPath{
{`true`, Path{}, true, Ok},
{`false`, Path{}, false, Ok},
{`null`, Path{}, nil, Ok},
{`12345`, Path{}, 12345.0, Ok},
{`12345.6789`, Path{}, 12345.6789, Ok},
{`"abc"`, Path{}, "abc", Ok},
{`"a\"\\bc"`, Path{}, "a\"\\bc", Ok},
{`{"a":1}`, Path{"a"}, 1.0, Ok},
{`[1,2,3]`, Path{0}, 1.0, Ok},
{`[1,2,3]`, Path{1}, 2.0, Ok},
{`[1,2,3]`, Path{2}, 3.0, Ok},
{`[1,2,3]`, Path{2}, 3.0, Ok},
}
for _, test := range tests {
t.Run(test.json, func(t *testing.T) {
s := NewSearcher(test.json)
node, err1 := s.GetByPath(test.path...)
v, err2 := node.Interface()
assert.Equal(t, test.value, v)
ok := err1 == nil && err2 == nil
assert.Equal(t, test.ok, ok)
})
}
}

func TestSearcher_GetByPathError(t *testing.T) {
type Path = []interface{}
const Error = false
tests := []testGetByPath{
{`tru`, Path{}, true, Error},
{`fal`, Path{}, false, Error},
{`nul`, Path{}, nil, Error},
{`{"a":1`, Path{}, nil, Error},
{`x12345.6789`, Path{}, 12345.6789, Error},
{`"abc`, Path{}, "abc", Error},
{`"a\"\\bc`, Path{}, "a\"\\bc", Error},
{`{"a":`, Path{"a"}, 1.0, Error},
{`[1,2,3]`, Path{4}, 1.0, Error},
{`[1,2,3]`, Path{"a"}, 3.0, Error},
}
for _, test := range tests {
t.Run(test.json, func(t *testing.T) {
s := NewSearcher(test.json)
_, err := s.GetByPath(test.path...)
assert.Equal(t, test.ok, err == nil)
})
}
}

func TestSearcher_GetByPathErr(t *testing.T) {
s := NewSearcher(` { "xx" : [] ,"yy" :{ }, "test" : [ true , 0.1 , "abc", ["h"], {"a":"bc"} ], "err1":[a, ] , "err2":{ ,"x":"xx"} } `)
node, e := s.GetByPath("zz")
Expand Down
14,404 changes: 6,862 additions & 7,542 deletions internal/native/avx/native_amd64.s

Large diffs are not rendered by default.

60 changes: 30 additions & 30 deletions internal/native/avx/native_subr_amd64.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 10e45e9

Please sign in to comment.