Sign in

Search issue titles and bodies, change requests and comments. Private repositories you cannot read are not included.

vole
Clone

Read only, no credentials:

https://rodent.software/vole.git

Write over SSH with a registered key:

git clone ssh://git@rodent.software:2222/vole.git

A free and open-source forge that lives in your Git repo.

Code

395 commit(s) on main

update readme Keenan Nemetz · 28m ago 32290114
history blame raw 2.7 KiB
1package ci
2
3import (
4 "path"
5 "path/filepath"
6 "strings"
7 "testing"
8)
9
10// FuzzValidateArtifactPath drives the check on the glob a workflow uses to declare
11// its artifacts. The pattern is matched against slash-separated paths relative to
12// the job's checkout, so what has to hold is that an accepted pattern describes a
13// place inside that checkout rather than above it.
14func FuzzValidateArtifactPath(f *testing.F) {
15 for _, seed := range []string{
16 "dist/vole-linux-*",
17 "dist/*.deb",
18 "*",
19 "**",
20 "../outside",
21 "a/../../b",
22 "/absolute/*",
23 "dist/",
24 "",
25 "[.][.]/x",
26 "a\x00b",
27 "dist/{a,b}",
28 "a/..",
29 "..",
30 ".",
31 } {
32 f.Add(seed)
33 }
34 f.Fuzz(func(t *testing.T, pattern string) {
35 if err := ValidateArtifactPath(pattern); err != nil {
36 return
37 }
38 if strings.HasPrefix(pattern, "/") || filepath.IsAbs(pattern) {
39 t.Fatalf("ValidateArtifactPath(%q) accepted an absolute pattern", pattern)
40 }
41 for _, segment := range strings.Split(pattern, "/") {
42 if segment == ".." {
43 t.Fatalf("ValidateArtifactPath(%q) accepted a pattern that climbs", pattern)
44 }
45 }
46 // The collector matches this against a path it derived from the walk, so an
47 // accepted pattern has to be one path.Match can compile at all.
48 if _, err := path.Match(pattern, "probe"); err != nil {
49 t.Fatalf("ValidateArtifactPath(%q) accepted a pattern path.Match refuses: %v", pattern, err)
50 }
51 })
52}
53
54// FuzzValidatePagesPath is the same for a site directory, which is joined to the
55// checkout to find the tree a site is published from. That one does reach a
56// filesystem, so the climb is the whole point.
57func FuzzValidatePagesPath(f *testing.F) {
58 for _, seed := range []string{
59 "site",
60 "site/",
61 "dist/site",
62 ".",
63 "",
64 "..",
65 "../site",
66 "site/../../etc",
67 "/absolute",
68 "site/*",
69 "site?",
70 "[a]",
71 "si:te",
72 "si\nte",
73 "a\x00b",
74 "....//x",
75 } {
76 f.Add(seed)
77 }
78 f.Fuzz(func(t *testing.T, dir string) {
79 if err := ValidatePagesPath(dir); err != nil {
80 return
81 }
82 if strings.HasPrefix(dir, "/") || filepath.IsAbs(dir) {
83 t.Fatalf("ValidatePagesPath(%q) accepted an absolute directory", dir)
84 }
85 for _, segment := range strings.Split(dir, "/") {
86 if segment == ".." {
87 t.Fatalf("ValidatePagesPath(%q) accepted a directory that climbs", dir)
88 }
89 }
90 if strings.ContainsAny(dir, "*?[\x00\r\n:") {
91 t.Fatalf("ValidatePagesPath(%q) accepted a character it is supposed to refuse", dir)
92 }
93 // Stated the way the caller uses it: joined to the checkout, the result is
94 // still inside the checkout.
95 joined := filepath.Join("/checkout", dir)
96 if joined != "/checkout" && !strings.HasPrefix(joined+string(filepath.Separator), "/checkout"+string(filepath.Separator)) {
97 t.Fatalf("ValidatePagesPath(%q) accepted %q, which resolves to %q", dir, dir, joined)
98 }
99 })
100}
101