Skip to content

Commit d2b5ad6

Browse files
committed
chore: fix an edge case that causes a panic
1 parent 6ae5651 commit d2b5ad6

File tree

3 files changed

+55
-50
lines changed

3 files changed

+55
-50
lines changed

pkg/jsonpath/parser.go

+3
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,9 @@ func (p *JSONPath) parseInnerSegment() (retValue *innerSegment, err error) {
141141
return nil, err
142142
}
143143
selectors = append(selectors, innerSelector)
144+
if len(p.tokens) <= p.current {
145+
return nil, p.parseFailure(&p.tokens[p.current-1], "unexpected end of input")
146+
}
144147
if p.tokens[p.current].Token == token.BRACKET_RIGHT {
145148
break
146149
} else if p.tokens[p.current].Token == token.COMMA {

pkg/jsonpath/parser_test.go

+52-50
Original file line numberDiff line numberDiff line change
@@ -1,89 +1,91 @@
1-
package jsonpath
1+
package jsonpath_test
22

33
import (
4-
"github.com/speakeasy-api/jsonpath/pkg/jsonpath/token"
4+
"github.com/speakeasy-api/jsonpath/pkg/jsonpath"
5+
"github.com/stretchr/testify/require"
56
"testing"
67
)
78

89
func TestParser(t *testing.T) {
910
tests := []struct {
10-
name string
11-
input string
12-
expected string
11+
name string
12+
input string
13+
invalid bool
1314
}{
1415
{
15-
name: "Root node",
16-
input: "$",
17-
expected: "$\n",
16+
name: "Root node",
17+
input: "$",
1818
},
1919
{
20-
name: "Single Dot child",
21-
input: "$.store",
22-
expected: "$\n├── store\n└── book\n",
20+
name: "Single Dot child",
21+
input: "$.store",
2322
},
2423
{
25-
name: "Single Bracket child",
26-
input: "$['store']",
27-
expected: "$\n├── store\n",
24+
name: "Single Bracket child",
25+
input: "$['store']",
2826
},
2927
{
30-
name: "Bracket child",
31-
input: "$['store']['book']",
32-
expected: "$\n├── ['store']\n└── ['book']\n",
28+
name: "Bracket child",
29+
input: "$['store']['book']",
3330
},
3431
{
35-
name: "Array index",
36-
input: "$[0]",
37-
expected: "$\n└── [0]\n",
32+
name: "Array index",
33+
input: "$[0]",
3834
},
3935
{
40-
name: "Array slice",
41-
input: "$[1:3]",
42-
expected: "$\n└── [1:3]\n ├── 1\n └── 3\n",
36+
name: "Array slice",
37+
input: "$[1:3]",
4338
},
4439
{
45-
name: "Array slice with step",
46-
input: "$[0:5:2]",
47-
expected: "$\n└── [0:5:2]\n ├── 0\n ├── 5\n └── 2\n",
40+
name: "Array slice with step",
41+
input: "$[0:5:2]",
4842
},
4943
{
50-
name: "Array slice with negative step",
51-
input: "$[5:1:-2]",
52-
expected: "$\n└── [5:1:-2]\n ├── 5\n ├── 1\n └── -2\n",
44+
name: "Array slice with negative step",
45+
input: "$[5:1:-2]",
5346
},
5447
{
55-
name: "Filter expression",
56-
input: "$[?(@.price < 10)]",
57-
expected: "$\n└── [?@ < 10]\n ├── @\n └── 10\n",
48+
name: "Filter expression",
49+
input: "$[?(@.price < 10)]",
5850
},
5951
{
60-
name: "Nested filter expression",
61-
input: "$[?(@.price < 10 && @.category == 'fiction')]",
62-
expected: "$\n└── [?@ < 10 && @ == 'fiction']\n ├── @ < 10\n │ ├── @\n │ └── 10\n └── @ == 'fiction'\n ├── @\n └── 'fiction'\n",
52+
name: "Nested filter expression",
53+
input: "$[?(@.price < 10 && @.category == 'fiction')]",
6354
},
6455
{
65-
name: "Function call",
66-
input: "$.books[?(length(@) > 100)]",
67-
expected: "$\n├── books\n└── [?length() > 100]\n └── length() > 100\n ├── length()\n └── 100\n",
56+
name: "Function call",
57+
input: "$.books[?(length(@) > 100)]",
58+
},
59+
{
60+
name: "Invalid missing closing ]",
61+
input: "$.paths.['/pet'",
62+
invalid: true,
63+
},
64+
{
65+
name: "Invalid extra input",
66+
input: "$.paths.['/pet')",
67+
invalid: true,
68+
},
69+
{
70+
name: "Valid filter",
71+
input: "$.paths[?(1 == 1)]",
72+
},
73+
{
74+
name: "Invalid filter",
75+
input: "$.paths[?(true]",
76+
invalid: true,
6877
},
6978
}
7079

7180
for _, test := range tests {
7281
t.Run(test.name, func(t *testing.T) {
73-
tokenizer := token.NewTokenizer(test.input)
74-
75-
parser := newParserPrivate(tokenizer, tokenizer.Tokenize())
76-
err := parser.parse()
77-
78-
if err != nil {
79-
t.Errorf("Unexpected error: %v", err)
82+
path, err := jsonpath.NewPath(test.input)
83+
if test.invalid {
84+
require.Error(t, err)
8085
return
8186
}
82-
//
83-
//actual := PrintSegments(parser.segments)
84-
//if actual != test.expected {
85-
// t.Errorf("Expected:\n%s\nGot:\n%s", test.expected, actual)
86-
//}
87+
require.NoError(t, err)
88+
require.Equal(t, test.input, path.String())
8789
})
8890
}
8991
}

web/src/assets/wasm/lib.wasm

754 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)