From: Russ Cox Date: Wed, 19 Oct 2016 04:01:31 +0000 (-0400) Subject: path/filepath: fix match of \\?\c:\* on Windows X-Git-Tag: go1.8beta1~683 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=452bbfc179d6739a404aacc819ec66acc71fc55c;p=gostls13.git 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 --- 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:\*`) +}