File tree Expand file tree Collapse file tree 3 files changed +23
-14
lines changed Expand file tree Collapse file tree 3 files changed +23
-14
lines changed Original file line number Diff line number Diff line change @@ -15,6 +15,7 @@ import (
15
15
"errors"
16
16
"io/fs"
17
17
"os"
18
+ "runtime"
18
19
"sort"
19
20
"strings"
20
21
)
@@ -117,21 +118,9 @@ func Clean(path string) string {
117
118
case os .IsPathSeparator (path [r ]):
118
119
// empty path element
119
120
r ++
120
- case path [r ] == '.' && r + 1 == n :
121
+ case path [r ] == '.' && ( r + 1 == n || os . IsPathSeparator ( path [ r + 1 ])) :
121
122
// . element
122
123
r ++
123
- case path [r ] == '.' && os .IsPathSeparator (path [r + 1 ]):
124
- // ./ element
125
- r ++
126
-
127
- for r < len (path ) && os .IsPathSeparator (path [r ]) {
128
- r ++
129
- }
130
- if out .w == 0 && volumeNameLen (path [r :]) > 0 {
131
- // When joining prefix "." and an absolute path on Windows,
132
- // the prefix should not be removed.
133
- out .append ('.' )
134
- }
135
124
case path [r ] == '.' && path [r + 1 ] == '.' && (r + 2 == n || os .IsPathSeparator (path [r + 2 ])):
136
125
// .. element: remove to last separator
137
126
r += 2
@@ -157,6 +146,18 @@ func Clean(path string) string {
157
146
if rooted && out .w != 1 || ! rooted && out .w != 0 {
158
147
out .append (Separator )
159
148
}
149
+ // If a ':' appears in the path element at the start of a Windows path,
150
+ // insert a .\ at the beginning to avoid converting relative paths
151
+ // like a/../c: into c:.
152
+ if runtime .GOOS == "windows" && out .w == 0 && out .volLen == 0 && r != 0 {
153
+ for i := r ; i < n && ! os .IsPathSeparator (path [i ]); i ++ {
154
+ if path [i ] == ':' {
155
+ out .append ('.' )
156
+ out .append (Separator )
157
+ break
158
+ }
159
+ }
160
+ }
160
161
// copy element
161
162
for ; r < n && ! os .IsPathSeparator (path [r ]); r ++ {
162
163
out .append (path [r ])
Original file line number Diff line number Diff line change @@ -106,6 +106,13 @@ var wincleantests = []PathTest{
106
106
{`//abc` , `\\abc` },
107
107
{`///abc` , `\\\abc` },
108
108
{`//abc//` , `\\abc\\` },
109
+
110
+ // Don't allow cleaning to move an element with a colon to the start of the path.
111
+ {`a/../c:` , `.\c:` },
112
+ {`a\..\c:` , `.\c:` },
113
+ {`a/../c:/a` , `.\c:\a` },
114
+ {`a/../../c:` , `..\c:` },
115
+ {`foo:bar` , `foo:bar` },
109
116
}
110
117
111
118
func TestClean (t * testing.T ) {
@@ -174,6 +181,7 @@ var winislocaltests = []IsLocalTest{
174
181
{`C:` , false },
175
182
{`C:\a` , false },
176
183
{`..\a` , false },
184
+ {`a/../c:` , false },
177
185
{`CONIN$` , false },
178
186
{`conin$` , false },
179
187
{`CONOUT$` , false },
Original file line number Diff line number Diff line change @@ -542,7 +542,7 @@ func TestIssue52476(t *testing.T) {
542
542
}{
543
543
{`..\.` , `C:` , `..\C:` },
544
544
{`..` , `C:` , `..\C:` },
545
- {`.` , `:` , `:` },
545
+ {`.` , `:` , `.\ :` },
546
546
{`.` , `C:` , `.\C:` },
547
547
{`.` , `C:/a/b/../c` , `.\C:\a\c` },
548
548
{`.` , `\C:` , `.\C:` },
You can’t perform that action at this time.
0 commit comments