Skip to content

Commit a26322e

Browse files
anderseknertjohanfylling
authored andcommitted
Fix issue where path in walk would get mutated (#7657)
I'm still not sure where this mutation occurs, as the append operation done in `walk` returns a copy and shouldn't mutate. But at least creating a shallow copy rather than a slice fixes the issue, and is still quite performant compared to the previous implementation that did a deep-copy of the path in each iteration. Fixes #7656 Signed-off-by: Anders Eknert <[email protected]> (cherry picked from commit 9d0557b)
1 parent b7d0a13 commit a26322e

File tree

2 files changed

+38
-3
lines changed

2 files changed

+38
-3
lines changed
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
---
2+
cases:
3+
# verify fix for issue 7656
4+
- note: walkbuiltin/array path not overwritten
5+
query: data.generated.p = x
6+
modules:
7+
- |
8+
package generated
9+
10+
x := {"a": [{"b": [{"c": [
11+
{"aa": "AA"},
12+
{"bb": "BB"},
13+
{"cc": "CC"},
14+
{"dd": "DDD"},
15+
]}]}]}
16+
17+
p := {path: value |
18+
[path, value] := walk(x)
19+
count(value) == 2
20+
}
21+
data: {}
22+
want_result:
23+
- x:
24+
"[\"a\",0,\"b\",0,\"c\",0,\"aa\"]": "AA"
25+
"[\"a\",0,\"b\",0,\"c\",1,\"bb\"]": "BB"
26+
"[\"a\",0,\"b\",0,\"c\",2,\"cc\"]": "CC"

v1/topdown/walk.go

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ func walk(filter, path *ast.Array, input *ast.Term, iter func(*ast.Term) error)
3030
pathCopy = ast.InternedEmptyArrayValue
3131
} else {
3232
// Shallow copy, as while the array is modified, the elements are not
33-
pathCopy = path.Slice(0, path.Len())
33+
pathCopy = copyShallow(path)
3434
}
3535

3636
// TODO(ae): I'd *really* like these terms to be retrieved from a sync.Pool, and
@@ -48,8 +48,7 @@ func walk(filter, path *ast.Array, input *ast.Term, iter func(*ast.Term) error)
4848
filter = filter.Slice(1, -1)
4949
if key.IsGround() {
5050
if term := input.Get(key); term != nil {
51-
path = pathAppend(path, key)
52-
return walk(filter, path, term, iter)
51+
return walk(filter, pathAppend(path, key), term, iter)
5352
}
5453
return nil
5554
}
@@ -149,6 +148,16 @@ func pathIsWildcard(operands []*ast.Term) bool {
149148
return false
150149
}
151150

151+
func copyShallow(arr *ast.Array) *ast.Array {
152+
cpy := make([]*ast.Term, 0, arr.Len())
153+
154+
arr.Foreach(func(elem *ast.Term) {
155+
cpy = append(cpy, elem)
156+
})
157+
158+
return ast.NewArray(cpy...)
159+
}
160+
152161
func init() {
153162
RegisterBuiltinFunc(ast.WalkBuiltin.Name, evalWalk)
154163
}

0 commit comments

Comments
 (0)