aboutsummaryrefslogtreecommitdiff
path: root/src/path/filepath
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2016-10-19 00:01:31 -0400
committerRuss Cox <rsc@golang.org>2016-10-24 16:24:20 +0000
commit452bbfc179d6739a404aacc819ec66acc71fc55c (patch)
treebf4ce233f6c731f3942a44cdbe321b1c61bf1328 /src/path/filepath
parentc5ccbdd22bdbdc43d541b7e7d4ed66ceb559030e (diff)
downloadgo-452bbfc179d6739a404aacc819ec66acc71fc55c.tar.xz
path/filepath: fix match of \\?\c:\* on Windows
\\?\c:\ is a "root directory" that is not subject to further matching, but the ? makes it look like a pattern, which was causing an infinite recursion. Make sure the code understands the ? is not a pattern. Fixes #15879. Change-Id: I3a4310bbc398bcae764b9f8859c875317345e757 Reviewed-on: https://go-review.googlesource.com/31460 Reviewed-by: Quentin Smith <quentin@golang.org>
Diffstat (limited to 'src/path/filepath')
-rw-r--r--src/path/filepath/match.go18
-rw-r--r--src/path/filepath/path_windows.go2
-rw-r--r--src/path/filepath/path_windows_test.go8
3 files changed, 20 insertions, 8 deletions
diff --git a/src/path/filepath/match.go b/src/path/filepath/match.go
index 9fa68f578d..5168e037b5 100644
--- a/src/path/filepath/match.go
+++ b/src/path/filepath/match.go
@@ -240,13 +240,14 @@ func Glob(pattern string) (matches []string, err error) {
}
dir, file := Split(pattern)
+ volumeLen := 0
if runtime.GOOS == "windows" {
- dir = cleanGlobPathWindows(dir)
+ volumeLen, dir = cleanGlobPathWindows(dir)
} else {
dir = cleanGlobPath(dir)
}
- if !hasMeta(dir) {
+ if !hasMeta(dir[volumeLen:]) {
return glob(dir, file, nil)
}
@@ -283,18 +284,21 @@ func cleanGlobPath(path string) string {
}
// cleanGlobPathWindows is windows version of cleanGlobPath.
-func cleanGlobPathWindows(path string) string {
+func cleanGlobPathWindows(path string) (prefixLen int, cleaned string) {
vollen := volumeNameLen(path)
switch {
case path == "":
- return "."
+ return 0, "."
case vollen+1 == len(path) && os.IsPathSeparator(path[len(path)-1]): // /, \, C:\ and C:/
// do nothing to the path
- return path
+ return vollen + 1, path
case vollen == len(path) && len(path) == 2: // C:
- return path + "." // convert C: into C:.
+ return vollen, path + "." // convert C: into C:.
default:
- return path[0 : len(path)-1] // chop off trailing separator
+ if vollen >= len(path) {
+ vollen = len(path) - 1
+ }
+ return vollen, path[0 : len(path)-1] // chop off trailing separator
}
}
diff --git a/src/path/filepath/path_windows.go b/src/path/filepath/path_windows.go
index 41c57df738..a74b6469a9 100644
--- a/src/path/filepath/path_windows.go
+++ b/src/path/filepath/path_windows.go
@@ -37,7 +37,7 @@ func volumeNameLen(path string) int {
if path[1] == ':' && ('a' <= c && c <= 'z' || 'A' <= c && c <= 'Z') {
return 2
}
- // is it UNC
+ // is it UNC? https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx
if l := len(path); l >= 5 && isSlash(path[0]) && isSlash(path[1]) &&
!isSlash(path[2]) && path[2] != '.' {
// first, leading `\\` and next shouldn't be `\`. its server name.
diff --git a/src/path/filepath/path_windows_test.go b/src/path/filepath/path_windows_test.go
index 8d552d06f7..6393629ccc 100644
--- a/src/path/filepath/path_windows_test.go
+++ b/src/path/filepath/path_windows_test.go
@@ -12,6 +12,7 @@ import (
"os/exec"
"path/filepath"
"reflect"
+ "runtime/debug"
"strings"
"testing"
)
@@ -413,3 +414,10 @@ func TestToNorm(t *testing.T) {
}
}
}
+
+func TestUNC(t *testing.T) {
+ // Test that this doesn't go into an infinite recursion.
+ // See golang.org/issue/15879.
+ defer debug.SetMaxStack(debug.SetMaxStack(1e6))
+ filepath.Glob(`\\?\c:\*`)
+}