Skip to content

Commit 81fa7c3

Browse files
committed
Merge #23
1 parent 020a251 commit 81fa7c3

File tree

2 files changed

+38
-26
lines changed

2 files changed

+38
-26
lines changed

parser.go

Lines changed: 23 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,17 @@ import (
1010
)
1111

1212
// Find position of next character which is not ' ', ',', '}' or ']'
13-
func nextValue(data []byte) int {
13+
func nextValue(data []byte, skipComma bool) int {
1414
for i, c := range data {
1515
switch c {
16-
case ' ', '\n', '\r', '\t', ',':
16+
case ' ', '\n', '\r', '\t':
1717
continue
18+
case ',':
19+
if !skipComma {
20+
continue
21+
} else {
22+
return i
23+
}
1824
default:
1925
return i
2026
}
@@ -82,43 +88,35 @@ func searchKeys(data []byte, keys ...string) int {
8288
ln := len(data)
8389
lk := len(keys)
8490

85-
for true {
86-
if i >= ln {
87-
return -1
88-
}
89-
91+
for i < ln {
9092
switch data[i] {
9193
case '"':
9294
i++
95+
keyBegin := i
9396

94-
se := stringEnd(data[i:])
95-
if se == -1 {
97+
strEnd := stringEnd(data[i:])
98+
if strEnd == -1 {
9699
return -1
97100
}
101+
i += strEnd
102+
keyEnd := i - 1
98103

99-
nO := nextValue(data[i+se:])
100-
101-
if nO == -1 {
104+
valueOffset := nextValue(data[i:], true)
105+
if valueOffset == -1 {
102106
return -1
103107
}
108+
i += valueOffset
104109

105-
if ln > i+se+nO &&
106-
data[i+se+nO] == ':' && // if string is a Key, and key level match
110+
if i < ln &&
111+
data[i] == ':' && // if string is a Key, and key level match
107112
keyLevel == level-1 && // If key nesting level match current object nested level
108-
109-
// Checks to speedup key comparsion
110-
len(keys[level-1]) == se-1 && // if it have same length
111-
data[i] == keys[level-1][0] { // If first character same
112-
if keys[level-1] == unsafeBytesToString(data[i:i+se-1]) {
113+
keys[level-1] == unsafeBytesToString(data[keyBegin:keyEnd]) {
113114
keyLevel++
114115
// If we found all keys in path
115116
if keyLevel == lk {
116-
return i + se + nO + 1
117+
return i + 1
117118
}
118-
}
119119
}
120-
121-
i += se + nO - 1
122120
case '{':
123121
level++
124122
case '}':
@@ -167,7 +165,7 @@ func Get(data []byte, keys ...string) (value []byte, dataType int, offset int, e
167165
}
168166

169167
// Go to closest value
170-
nO := nextValue(data[offset:])
168+
nO := nextValue(data[offset:], false)
171169

172170
if nO == -1 {
173171
return []byte{}, NotExist, -1, errors.New("Malformed JSON error")
@@ -176,7 +174,6 @@ func Get(data []byte, keys ...string) (value []byte, dataType int, offset int, e
176174
offset += nO
177175

178176
endOffset := offset
179-
180177
// if string value
181178
if data[offset] == '"' {
182179
dataType = String
@@ -267,7 +264,7 @@ func ArrayEach(data []byte, cb func(value []byte, dataType int, offset int, err
267264
}
268265

269266
// Go to closest value
270-
nO := nextValue(data[offset:])
267+
nO := nextValue(data[offset:], false)
271268

272269
if nO == -1 {
273270
return errors.New("Malformed JSON")

parser_test.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ import (
77
"testing"
88
)
99

10+
// Set it to non-empty value if want to run only specific test
11+
var activeTest = ""
12+
1013
func toArray(data []byte) (result [][]byte) {
1114
ArrayEach(data, func(value []byte, dataType int, offset int, err error) {
1215
result = append(result, value)
@@ -237,6 +240,12 @@ var getTests = []Test{
237240
path: []string{"a"},
238241
isErr: true,
239242
},
243+
Test{
244+
desc: "malformed key (followed by comma followed by colon)",
245+
json: `{"a",:1}`,
246+
path: []string{"a"},
247+
isErr: true,
248+
},
240249
}
241250

242251
var getIntTests = []Test{
@@ -399,6 +408,12 @@ func checkFoundAndNoError(t *testing.T, testKind string, test Test, jtype int, v
399408

400409
func runTests(t *testing.T, tests []Test, runner func(Test) (interface{}, int, error), typeChecker func(Test, interface{}) (bool, interface{})) {
401410
for _, test := range tests {
411+
if activeTest != "" && test.desc != activeTest {
412+
continue
413+
}
414+
415+
// fmt.Println("Running:", test.desc)
416+
402417
value, dataType, err := runner(test)
403418

404419
if checkFoundAndNoError(t, "Get()", test, dataType, value, err) {

0 commit comments

Comments
 (0)