Skip to content

Commit 8e0271b

Browse files
TT-17940: fix gromit rendering the wrong content when bundle files share a filename (#528)
1 parent 0ac2166 commit 8e0271b

28 files changed

Lines changed: 257 additions & 421 deletions

File tree

policy/bundle.go

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -211,8 +211,7 @@ func fsTreeWalk(b *Bundle, tfs fs.FS, root string, subTemps []string) error {
211211
return fs.SkipDir
212212
}
213213
if !d.IsDir() {
214-
// The top-level template must be the first element
215-
subTemps = append([]string{path}, subTemps...)
214+
files := append([]string{path}, subTemps...)
216215

217216
stPath := path + ".d"
218217
fi, err := fs.Stat(tfs, stPath)
@@ -222,18 +221,18 @@ func fsTreeWalk(b *Bundle, tfs fs.FS, root string, subTemps []string) error {
222221
return err
223222
}
224223
for _, de := range des {
225-
subTemps = append(subTemps, filepath.Join(stPath, de.Name()))
224+
files = append(files, filepath.Join(stPath, de.Name()))
226225
}
227226
}
228227
// Normalize the path to use '/' as the separator
229228
path = strings.ReplaceAll(path, string(os.PathSeparator), "/")
230-
log.Trace().Strs("files", subTemps).Str("template", d.Name()).Msg("adding to bundle")
229+
log.Trace().Strs("files", files).Str("template", d.Name()).Msg("adding to bundle")
231230

232231
t := template.Must(
233232
template.New(d.Name()).
234233
Funcs(sprig.TxtFuncMap()).
235234
Option("missingkey=error").
236-
ParseFS(tfs, subTemps...))
235+
ParseFS(tfs, files...))
237236
b.Add(path, t)
238237
}
239238
return nil

policy/bundle_test.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
package policy
22

33
import (
4+
"bytes"
45
"os"
56
"path/filepath"
67
"slices"
78
"testing"
9+
"testing/fstest"
810

911
"github.com/TykTechnologies/gromit/config"
1012
)
@@ -85,6 +87,49 @@ func TestBundleRender(t *testing.T) {
8587
}
8688
}
8789

90+
// TestFsTreeWalkBasenameCollision guards against parse-list leakage
91+
// between bundle files that share a base name. text/template names
92+
// templates by base name and the last duplicate parsed wins, so if the
93+
// parse list accumulates across the walk, .github/zizmor.yml (zizmor
94+
// config) and .github/workflows/zizmor.yml (caller workflow) would
95+
// render identical content.
96+
func TestFsTreeWalkBasenameCollision(t *testing.T) {
97+
tfs := fstest.MapFS{
98+
"templates/test/.github/zizmor.yml": &fstest.MapFile{Data: []byte("kind: config")},
99+
"templates/test/.github/workflows/zizmor.yml": &fstest.MapFile{Data: []byte("kind: workflow")},
100+
}
101+
b := &Bundle{Name: "test", tree: &bundleNode{}}
102+
if err := fsTreeWalk(b, tfs, "templates/test", nil); err != nil {
103+
t.Fatalf("fsTreeWalk: %v", err)
104+
}
105+
106+
got := make(map[string]string)
107+
var walk func(n *bundleNode)
108+
walk = func(n *bundleNode) {
109+
for _, c := range n.Children {
110+
walk(c)
111+
}
112+
if len(n.Children) == 0 && n.template != nil {
113+
var buf bytes.Buffer
114+
if err := n.template.Execute(&buf, nil); err != nil {
115+
t.Fatalf("rendering %s: %v", n.path, err)
116+
}
117+
got[n.path] = buf.String()
118+
}
119+
}
120+
walk(b.tree)
121+
122+
want := map[string]string{
123+
".github/zizmor.yml": "kind: config",
124+
".github/workflows/zizmor.yml": "kind: workflow",
125+
}
126+
for path, content := range want {
127+
if got[path] != content {
128+
t.Errorf("%s rendered %q, want %q", path, got[path], content)
129+
}
130+
}
131+
}
132+
88133
func countFiles(tmpDir string) (int, error) {
89134
count := 0
90135
err := filepath.Walk(tmpDir, func(path string, info os.FileInfo, err error) error {
Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,10 @@
11
# Generated by: gromit policy
22
# This file is managed by gromit, do not edit by hand.
3-
name: zizmor
4-
on:
5-
pull_request:
6-
push:
7-
branches:
8-
- main
9-
permissions: {}
10-
jobs:
11-
zizmor:
12-
uses: TykTechnologies/github-actions/.github/workflows/zizmor.yml@production
13-
permissions:
14-
security-events: write
15-
contents: read
16-
actions: read
17-
secrets:
18-
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
3+
# zizmor configuration (https://docs.zizmor.sh/configuration/)
4+
rules:
5+
unpinned-uses:
6+
config:
7+
policies:
8+
# First-party refs use mutable tags (production/main) by design.
9+
"TykTechnologies/*": ref-pin
10+
"*": hash-pin
Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,10 @@
11
# Generated by: gromit policy
22
# This file is managed by gromit, do not edit by hand.
3-
name: zizmor
4-
on:
5-
pull_request:
6-
push:
7-
branches:
8-
- main
9-
permissions: {}
10-
jobs:
11-
zizmor:
12-
uses: TykTechnologies/github-actions/.github/workflows/zizmor.yml@production
13-
permissions:
14-
security-events: write
15-
contents: read
16-
actions: read
17-
secrets:
18-
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
3+
# zizmor configuration (https://docs.zizmor.sh/configuration/)
4+
rules:
5+
unpinned-uses:
6+
config:
7+
policies:
8+
# First-party refs use mutable tags (production/main) by design.
9+
"TykTechnologies/*": ref-pin
10+
"*": hash-pin
Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,10 @@
11
# Generated by: gromit policy
22
# This file is managed by gromit, do not edit by hand.
3-
name: zizmor
4-
on:
5-
pull_request:
6-
push:
7-
branches:
8-
- master
9-
permissions: {}
10-
jobs:
11-
zizmor:
12-
uses: TykTechnologies/github-actions/.github/workflows/zizmor.yml@production
13-
permissions:
14-
security-events: write
15-
contents: read
16-
actions: read
17-
secrets:
18-
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
3+
# zizmor configuration (https://docs.zizmor.sh/configuration/)
4+
rules:
5+
unpinned-uses:
6+
config:
7+
policies:
8+
# First-party refs use mutable tags (production/main) by design.
9+
"TykTechnologies/*": ref-pin
10+
"*": hash-pin
Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,10 @@
11
# Generated by: gromit policy
22
# This file is managed by gromit, do not edit by hand.
3-
name: zizmor
4-
on:
5-
pull_request:
6-
push:
7-
branches:
8-
- master
9-
permissions: {}
10-
jobs:
11-
zizmor:
12-
uses: TykTechnologies/github-actions/.github/workflows/zizmor.yml@production
13-
permissions:
14-
security-events: write
15-
contents: read
16-
actions: read
17-
secrets:
18-
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
3+
# zizmor configuration (https://docs.zizmor.sh/configuration/)
4+
rules:
5+
unpinned-uses:
6+
config:
7+
policies:
8+
# First-party refs use mutable tags (production/main) by design.
9+
"TykTechnologies/*": ref-pin
10+
"*": hash-pin
Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,10 @@
11
# Generated by: gromit policy
22
# This file is managed by gromit, do not edit by hand.
3-
name: zizmor
4-
on:
5-
pull_request:
6-
push:
7-
branches:
8-
- release-5.13.1
9-
permissions: {}
10-
jobs:
11-
zizmor:
12-
uses: TykTechnologies/github-actions/.github/workflows/zizmor.yml@production
13-
permissions:
14-
security-events: write
15-
contents: read
16-
actions: read
17-
secrets:
18-
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
3+
# zizmor configuration (https://docs.zizmor.sh/configuration/)
4+
rules:
5+
unpinned-uses:
6+
config:
7+
policies:
8+
# First-party refs use mutable tags (production/main) by design.
9+
"TykTechnologies/*": ref-pin
10+
"*": hash-pin
Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,10 @@
11
# Generated by: gromit policy
22
# This file is managed by gromit, do not edit by hand.
3-
name: zizmor
4-
on:
5-
pull_request:
6-
push:
7-
branches:
8-
- release-5.13
9-
permissions: {}
10-
jobs:
11-
zizmor:
12-
uses: TykTechnologies/github-actions/.github/workflows/zizmor.yml@production
13-
permissions:
14-
security-events: write
15-
contents: read
16-
actions: read
17-
secrets:
18-
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
3+
# zizmor configuration (https://docs.zizmor.sh/configuration/)
4+
rules:
5+
unpinned-uses:
6+
config:
7+
policies:
8+
# First-party refs use mutable tags (production/main) by design.
9+
"TykTechnologies/*": ref-pin
10+
"*": hash-pin
Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,10 @@
11
# Generated by: gromit policy
22
# This file is managed by gromit, do not edit by hand.
3-
name: zizmor
4-
on:
5-
pull_request:
6-
push:
7-
branches:
8-
- release-5.14.0
9-
permissions: {}
10-
jobs:
11-
zizmor:
12-
uses: TykTechnologies/github-actions/.github/workflows/zizmor.yml@production
13-
permissions:
14-
security-events: write
15-
contents: read
16-
actions: read
17-
secrets:
18-
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
3+
# zizmor configuration (https://docs.zizmor.sh/configuration/)
4+
rules:
5+
unpinned-uses:
6+
config:
7+
policies:
8+
# First-party refs use mutable tags (production/main) by design.
9+
"TykTechnologies/*": ref-pin
10+
"*": hash-pin
Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,10 @@
11
# Generated by: gromit policy
22
# This file is managed by gromit, do not edit by hand.
3-
name: zizmor
4-
on:
5-
pull_request:
6-
push:
7-
branches:
8-
- release-5.14
9-
permissions: {}
10-
jobs:
11-
zizmor:
12-
uses: TykTechnologies/github-actions/.github/workflows/zizmor.yml@production
13-
permissions:
14-
security-events: write
15-
contents: read
16-
actions: read
17-
secrets:
18-
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
3+
# zizmor configuration (https://docs.zizmor.sh/configuration/)
4+
rules:
5+
unpinned-uses:
6+
config:
7+
policies:
8+
# First-party refs use mutable tags (production/main) by design.
9+
"TykTechnologies/*": ref-pin
10+
"*": hash-pin

0 commit comments

Comments
 (0)