mirror of
https://github.com/golang/go
synced 2024-11-18 03:54:50 -07:00
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>
This commit is contained in:
parent
c5ccbdd22b
commit
452bbfc179
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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:\*`)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user