mirror of
https://github.com/golang/go
synced 2024-11-26 14:26:51 -07:00
path/filepath: consider \\?\c: as a volume on Windows
While fixing several bugs in path handling on Windows, beginning with \\?\. Prior to #540277, VolumeName considered the first path component after the \\?\ prefix to be part of the volume name. After, it considered only the \\? prefix to be the volume name. Restore the previous behavior. Fixes #64028 Change-Id: I6523789e61776342800bd607fb3f29d496257e68 Reviewed-on: https://go-review.googlesource.com/c/go/+/541175 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Roland Shoemaker <roland@golang.org>
This commit is contained in:
parent
130baf3d42
commit
eda42f7c60
@ -109,6 +109,8 @@ var wincleantests = []PathTest{
|
|||||||
{`//abc`, `\\abc`},
|
{`//abc`, `\\abc`},
|
||||||
{`///abc`, `\\\abc`},
|
{`///abc`, `\\\abc`},
|
||||||
{`//abc//`, `\\abc\\`},
|
{`//abc//`, `\\abc\\`},
|
||||||
|
{`\\?\C:\`, `\\?\C:\`},
|
||||||
|
{`\\?\C:\a`, `\\?\C:\a`},
|
||||||
|
|
||||||
// Don't allow cleaning to move an element with a colon to the start of the path.
|
// Don't allow cleaning to move an element with a colon to the start of the path.
|
||||||
{`a/../c:`, `.\c:`},
|
{`a/../c:`, `.\c:`},
|
||||||
@ -1597,10 +1599,13 @@ var volumenametests = []VolumeNameTest{
|
|||||||
{`//.`, `\\.`},
|
{`//.`, `\\.`},
|
||||||
{`//./`, `\\.\`},
|
{`//./`, `\\.\`},
|
||||||
{`//./NUL`, `\\.\NUL`},
|
{`//./NUL`, `\\.\NUL`},
|
||||||
{`//?/`, `\\?`},
|
{`//?`, `\\?`},
|
||||||
|
{`//?/`, `\\?\`},
|
||||||
|
{`//?/NUL`, `\\?\NUL`},
|
||||||
|
{`/??`, `\??`},
|
||||||
|
{`/??/`, `\??\`},
|
||||||
|
{`/??/NUL`, `\??\NUL`},
|
||||||
{`//./a/b`, `\\.\a`},
|
{`//./a/b`, `\\.\a`},
|
||||||
{`//?/`, `\\?`},
|
|
||||||
{`//?/`, `\\?`},
|
|
||||||
{`//./C:`, `\\.\C:`},
|
{`//./C:`, `\\.\C:`},
|
||||||
{`//./C:/`, `\\.\C:`},
|
{`//./C:/`, `\\.\C:`},
|
||||||
{`//./C:/a/b/c`, `\\.\C:`},
|
{`//./C:/a/b/c`, `\\.\C:`},
|
||||||
@ -1609,8 +1614,8 @@ var volumenametests = []VolumeNameTest{
|
|||||||
{`//./UNC/host\`, `\\.\UNC\host\`},
|
{`//./UNC/host\`, `\\.\UNC\host\`},
|
||||||
{`//./UNC`, `\\.\UNC`},
|
{`//./UNC`, `\\.\UNC`},
|
||||||
{`//./UNC/`, `\\.\UNC\`},
|
{`//./UNC/`, `\\.\UNC\`},
|
||||||
{`\\?\x`, `\\?`},
|
{`\\?\x`, `\\?\x`},
|
||||||
{`\??\x`, `\??`},
|
{`\??\x`, `\??\x`},
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestVolumeName(t *testing.T) {
|
func TestVolumeName(t *testing.T) {
|
||||||
|
@ -102,12 +102,14 @@ func volumeNameLen(path string) int {
|
|||||||
// \\.\unc\a\b\..\c into \\.\unc\a\c.
|
// \\.\unc\a\b\..\c into \\.\unc\a\c.
|
||||||
return uncLen(path, len(`\\.\UNC\`))
|
return uncLen(path, len(`\\.\UNC\`))
|
||||||
|
|
||||||
case pathHasPrefixFold(path, `\\.`):
|
case pathHasPrefixFold(path, `\\.`) ||
|
||||||
// Path starts with \\., and is a Local Device path.
|
pathHasPrefixFold(path, `\\?`) || pathHasPrefixFold(path, `\??`):
|
||||||
|
// Path starts with \\.\, and is a Local Device path; or
|
||||||
|
// path starts with \\?\ or \??\ and is a Root Local Device path.
|
||||||
//
|
//
|
||||||
// We currently treat the next component after the \\.\ prefix
|
// We treat the next component after the \\.\ prefix as
|
||||||
// as part of the volume name, although there doesn't seem to be
|
// part of the volume name, which means Clean(`\\?\c:\`)
|
||||||
// a principled reason to do this.
|
// won't remove the trailing \. (See #64028.)
|
||||||
if len(path) == 3 {
|
if len(path) == 3 {
|
||||||
return 3 // exactly \\.
|
return 3 // exactly \\.
|
||||||
}
|
}
|
||||||
@ -117,14 +119,6 @@ func volumeNameLen(path string) int {
|
|||||||
}
|
}
|
||||||
return len(path) - len(rest) - 1
|
return len(path) - len(rest) - 1
|
||||||
|
|
||||||
case pathHasPrefixFold(path, `\\?`) || pathHasPrefixFold(path, `\??`):
|
|
||||||
// Path starts with \\?\ or \??\, and is a Root Local Device path.
|
|
||||||
//
|
|
||||||
// While Windows usually treats / and \ as equivalent,
|
|
||||||
// /??/ does not seem to be recognized as a Root Local Device path.
|
|
||||||
// We treat it as one anyway here to be safe.
|
|
||||||
return 3
|
|
||||||
|
|
||||||
case len(path) >= 2 && isSlash(path[1]):
|
case len(path) >= 2 && isSlash(path[1]):
|
||||||
// Path starts with \\, and is a UNC path.
|
// Path starts with \\, and is a UNC path.
|
||||||
return uncLen(path, 2)
|
return uncLen(path, 2)
|
||||||
|
Loading…
Reference in New Issue
Block a user