Fixed modifier pipe issue

This commit fixes an issue where chaining modifiers that used a
string arg would fail to process the modifier following the first.

fixes #143
This commit is contained in:
tidwall 2019-11-18 09:51:37 -07:00
parent c34bf81952
commit 5c2e4b3824
2 changed files with 27 additions and 5 deletions

View File

@ -464,11 +464,13 @@ func ParseBytes(json []byte) Result {
} }
func squash(json string) string { func squash(json string) string {
// expects that the lead character is a '[' or '{' or '(' // expects that the lead character is a '[' or '{' or '(' or '"'
// squash the value, ignoring all nested arrays and objects. // squash the value, ignoring all nested arrays and objects.
// the first '[' or '{' or '(', has already been read var i, depth int
depth := 1 if json[0] != '"' {
for i := 1; i < len(json); i++ { i, depth = 1, 1
}
for ; i < len(json); i++ {
if json[i] >= '"' && json[i] <= '}' { if json[i] >= '"' && json[i] <= '}' {
switch json[i] { switch json[i] {
case '"': case '"':
@ -495,6 +497,9 @@ func squash(json string) string {
break break
} }
} }
if depth == 0 {
return json[:i+1]
}
case '{', '[', '(': case '{', '[', '(':
depth++ depth++
case '}', ']', ')': case '}', ']', ')':
@ -2713,7 +2718,7 @@ func execModifier(json, path string) (pathOut, res string, ok bool) {
case '{', '[', '"': case '{', '[', '"':
res := Parse(pathOut) res := Parse(pathOut)
if res.Exists() { if res.Exists() {
_, args = parseSquash(pathOut, 0) args = squash(pathOut)
pathOut = pathOut[len(args):] pathOut = pathOut[len(args):]
parsedArgs = true parsedArgs = true
} }

View File

@ -2023,3 +2023,20 @@ func TestIssue141(t *testing.T) {
assert(t, Get(json, "data.#.{q}|@ugly").Raw == `[{"q":11},{"q":21},{"q":31}]`) assert(t, Get(json, "data.#.{q}|@ugly").Raw == `[{"q":11},{"q":21},{"q":31}]`)
assert(t, Get(json, "data.#.q|@ugly").Raw == `[11,21,31]`) assert(t, Get(json, "data.#.q|@ugly").Raw == `[11,21,31]`)
} }
func TestChainedModifierStringArgs(t *testing.T) {
// issue #143
AddModifier("push", func(json, arg string) string {
json = strings.TrimSpace(json)
if len(json) < 2 || !Parse(json).IsArray() {
return json
}
json = strings.TrimSpace(json[1 : len(json)-1])
if len(json) == 0 {
return "[" + arg + "]"
}
return "[" + json + "," + arg + "]"
})
res := Get("[]", `@push:"2"|@push:"3"|@push:{"a":"b","c":["e","f"]}|@push:true|@push:10.23`)
assert(t, res.String() == `["2","3",{"a":"b","c":["e","f"]},true,10.23]`)
}