9
9
"io/ioutil"
10
10
"os"
11
11
"path/filepath"
12
+ "runtime"
12
13
"syscall"
13
14
"testing"
14
15
)
@@ -22,6 +23,11 @@ func symlink(t *testing.T, oldname, newname string) {
22
23
}
23
24
}
24
25
26
+ type input struct {
27
+ root , unsafe string
28
+ expected string
29
+ }
30
+
25
31
// Test basic handling of symlink expansion.
26
32
func TestSymlink (t * testing.T ) {
27
33
dir , err := ioutil .TempDir ("" , "TestSymlink" )
@@ -38,21 +44,26 @@ func TestSymlink(t *testing.T) {
38
44
symlink (t , "../../../../../../../../../../../../../etc" , filepath .Join (dir , "etclink" ))
39
45
symlink (t , "/../../../../../../../../../../../../../etc/passwd" , filepath .Join (dir , "passwd" ))
40
46
41
- for _ , test := range []struct {
42
- root , unsafe string
43
- expected string
44
- }{
47
+ rootOrVol := string (filepath .Separator )
48
+ if vol := filepath .VolumeName (dir ); vol != "" {
49
+ rootOrVol = vol + rootOrVol
50
+ }
51
+
52
+ tc := []input {
45
53
// Make sure that expansion with a root of '/' proceeds in the expected fashion.
46
- {"/" , filepath .Join (dir , "passwd" ), "/etc/passwd" },
47
- {"/" , filepath .Join (dir , "etclink" ), "/etc" },
48
- {"/" , filepath .Join (dir , "etc" ), filepath .Join (dir , "somepath" )},
54
+ {rootOrVol , filepath .Join (dir , "passwd" ), filepath .Join (rootOrVol , "etc" , "passwd" )},
55
+ {rootOrVol , filepath .Join (dir , "etclink" ), filepath .Join (rootOrVol , "etc" )},
56
+
57
+ {rootOrVol , filepath .Join (dir , "etc" ), filepath .Join (dir , "somepath" )},
49
58
// Now test scoped expansion.
50
59
{dir , "passwd" , filepath .Join (dir , "somepath" , "passwd" )},
51
60
{dir , "etclink" , filepath .Join (dir , "somepath" )},
52
61
{dir , "etc" , filepath .Join (dir , "somepath" )},
53
62
{dir , "etc/test" , filepath .Join (dir , "somepath" , "test" )},
54
63
{dir , "etc/test/.." , filepath .Join (dir , "somepath" )},
55
- } {
64
+ }
65
+
66
+ for _ , test := range tc {
56
67
got , err := SecureJoin (test .root , test .unsafe )
57
68
if err != nil {
58
69
t .Errorf ("securejoin(%q, %q): unexpected error: %v" , test .root , test .unsafe , err )
@@ -85,29 +96,31 @@ func TestNoSymlink(t *testing.T) {
85
96
}
86
97
defer os .RemoveAll (dir )
87
98
88
- for _ , test := range []struct {
89
- root , unsafe string
90
- }{
91
- // TODO: Do we need to have some conditional FromSlash handling here?
92
- {dir , "somepath" },
93
- {dir , "even/more/path" },
94
- {dir , "/this/is/a/path" },
95
- {dir , "also/a/../path/././/with/some/./.././junk" },
96
- {dir , "yetanother/../path/././/with/some/./.././junk../../../../../../../../../../../../etc/passwd" },
97
- {dir , "/../../../../../../../../../../../../../../../../etc/passwd" },
98
- {dir , "../../../../../../../../../../../../../../../../somedir" },
99
- {dir , "../../../../../../../../../../../../../../../../" },
100
- {dir , "./../../.././././../../../../../../../../../../../../../../../../etc passwd" },
101
- } {
102
- expected := filepath .Join (test .root , filepath .Clean (string (filepath .Separator )+ test .unsafe ))
99
+ tc := []input {
100
+ {dir , "somepath" , filepath .Join (dir , "somepath" )},
101
+ {dir , "even/more/path" , filepath .Join (dir , "even" , "more" , "path" )},
102
+ {dir , "/this/is/a/path" , filepath .Join (dir , "this" , "is" , "a" , "path" )},
103
+ {dir , "also/a/../path/././/with/some/./.././junk" , filepath .Join (dir , "also" , "path" , "with" , "junk" )},
104
+ {dir , "yetanother/../path/././/with/some/./.././junk../../../../../../../../../../../../etc/passwd" , filepath .Join (dir , "etc" , "passwd" )},
105
+ {dir , "/../../../../../../../../../../../../../../../../etc/passwd" , filepath .Join (dir , "etc" , "passwd" )},
106
+ {dir , "../../../../../../../../../../../../../../../../somedir" , filepath .Join (dir , "somedir" )},
107
+ {dir , "../../../../../../../../../../../../../../../../" , filepath .Join (dir )},
108
+ {dir , "./../../.././././../../../../../../../../../../../../../../../../etc passwd" , filepath .Join (dir , "etc passwd" )},
109
+ }
110
+
111
+ if runtime .GOOS == "windows" {
112
+ tc = append (tc , []input {
113
+ {dir , "d:\\ etc\\ test" , filepath .Join (dir , "etc" , "test" )},
114
+ }... )
115
+ }
116
+
117
+ for _ , test := range tc {
103
118
got , err := SecureJoin (test .root , test .unsafe )
104
119
if err != nil {
105
120
t .Errorf ("securejoin(%q, %q): unexpected error: %v" , test .root , test .unsafe , err )
106
- continue
107
121
}
108
- if got != expected {
109
- t .Errorf ("securejoin(%q, %q): expected %q, got %q" , test .root , test .unsafe , expected , got )
110
- continue
122
+ if got != test .expected {
123
+ t .Errorf ("securejoin(%q, %q): expected %q, got %q" , test .root , test .unsafe , test .expected , got )
111
124
}
112
125
}
113
126
}
@@ -130,10 +143,7 @@ func TestNonLexical(t *testing.T) {
130
143
symlink (t , "/../cousinparent/cousin" , filepath .Join (dir , "subdir" , "link2" ))
131
144
symlink (t , "/../../../../../../../../../../../../../../../../cousinparent/cousin" , filepath .Join (dir , "subdir" , "link3" ))
132
145
133
- for _ , test := range []struct {
134
- root , unsafe string
135
- expected string
136
- }{
146
+ for _ , test := range []input {
137
147
{dir , "subdir" , filepath .Join (dir , "subdir" )},
138
148
{dir , "subdir/link/test" , filepath .Join (dir , "cousinparent" , "cousin" , "test" )},
139
149
{dir , "subdir/link2/test" , filepath .Join (dir , "cousinparent" , "cousin" , "test" )},
@@ -188,7 +198,7 @@ func TestSymlinkLoop(t *testing.T) {
188
198
} {
189
199
got , err := SecureJoin (test .root , test .unsafe )
190
200
if ! errors .Is (err , syscall .ELOOP ) {
191
- t .Errorf ("securejoin(%q, %q): expected ELOOP, got %v & %q " , test .root , test .unsafe , err , got )
201
+ t .Errorf ("securejoin(%q, %q): expected ELOOP, got %q & %v " , test .root , test .unsafe , got , err )
192
202
continue
193
203
}
194
204
}
@@ -275,10 +285,7 @@ func TestSecureJoinVFS(t *testing.T) {
275
285
symlink (t , "/../cousinparent/cousin" , filepath .Join (dir , "subdir" , "link2" ))
276
286
symlink (t , "/../../../../../../../../../../../../../../../../cousinparent/cousin" , filepath .Join (dir , "subdir" , "link3" ))
277
287
278
- for _ , test := range []struct {
279
- root , unsafe string
280
- expected string
281
- }{
288
+ for _ , test := range []input {
282
289
{dir , "subdir" , filepath .Join (dir , "subdir" )},
283
290
{dir , "subdir/link/test" , filepath .Join (dir , "cousinparent" , "cousin" , "test" )},
284
291
{dir , "subdir/link2/test" , filepath .Join (dir , "cousinparent" , "cousin" , "test" )},
0 commit comments