Skip to content

Commit 4c69fd5

Browse files
mattndmitshur
authored andcommitted
[release-branch.go1.17] path/filepath: do not remove prefix "." when following path contains ":".
For #52476 Fixes #52478 Fixes CVE-2022-29804 Change-Id: I9eb72ac7dbccd6322d060291f31831dc389eb9bb Reviewed-on: https://go-review.googlesource.com/c/go/+/401595 Auto-Submit: Ian Lance Taylor <[email protected]> Reviewed-by: Alex Brainman <[email protected]> Run-TryBot: Ian Lance Taylor <[email protected]> Reviewed-by: Ian Lance Taylor <[email protected]> Reviewed-by: Damien Neil <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Reviewed-on: https://go-review.googlesource.com/c/go/+/405235 Reviewed-by: Yasuhiro Matsumoto <[email protected]>
1 parent 909881d commit 4c69fd5

File tree

3 files changed

+42
-1
lines changed

3 files changed

+42
-1
lines changed

src/path/filepath/path.go

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,9 +117,21 @@ func Clean(path string) string {
117117
case os.IsPathSeparator(path[r]):
118118
// empty path element
119119
r++
120-
case path[r] == '.' && (r+1 == n || os.IsPathSeparator(path[r+1])):
120+
case path[r] == '.' && r+1 == n:
121121
// . element
122122
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+
}
123135
case path[r] == '.' && path[r+1] == '.' && (r+2 == n || os.IsPathSeparator(path[r+2])):
124136
// .. element: remove to last separator
125137
r += 2

src/path/filepath/path_test.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,9 @@ var wincleantests = []PathTest{
9393
{`//host/share/foo/../baz`, `\\host\share\baz`},
9494
{`\\a\b\..\c`, `\\a\b\c`},
9595
{`\\a\b`, `\\a\b`},
96+
{`.\c:`, `.\c:`},
97+
{`.\c:\foo`, `.\c:\foo`},
98+
{`.\c:foo`, `.\c:foo`},
9699
}
97100

98101
func TestClean(t *testing.T) {

src/path/filepath/path_windows_test.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -530,3 +530,29 @@ func TestNTNamespaceSymlink(t *testing.T) {
530530
t.Errorf(`EvalSymlinks(%q): got %q, want %q`, filelink, got, want)
531531
}
532532
}
533+
534+
func TestIssue52476(t *testing.T) {
535+
tests := []struct {
536+
lhs, rhs string
537+
want string
538+
}{
539+
{`..\.`, `C:`, `..\C:`},
540+
{`..`, `C:`, `..\C:`},
541+
{`.`, `:`, `:`},
542+
{`.`, `C:`, `.\C:`},
543+
{`.`, `C:/a/b/../c`, `.\C:\a\c`},
544+
{`.`, `\C:`, `.\C:`},
545+
{`C:\`, `.`, `C:\`},
546+
{`C:\`, `C:\`, `C:\C:`},
547+
{`C`, `:`, `C\:`},
548+
{`\.`, `C:`, `\C:`},
549+
{`\`, `C:`, `\C:`},
550+
}
551+
552+
for _, test := range tests {
553+
got := filepath.Join(test.lhs, test.rhs)
554+
if got != test.want {
555+
t.Errorf(`Join(%q, %q): got %q, want %q`, test.lhs, test.rhs, got, test.want)
556+
}
557+
}
558+
}

0 commit comments

Comments
 (0)