lib/file: improve error message for create dir on non-existent network host on windows (#6420)

This commit is contained in:
albertony 2022-10-28 21:00:22 +02:00 committed by GitHub
parent 1fc864fb32
commit 65987f5970
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 27 additions and 7 deletions

View File

@ -11,8 +11,9 @@ import (
// MkdirAll creates a directory named path, along with any necessary parents. // MkdirAll creates a directory named path, along with any necessary parents.
// //
// Improves os.MkdirAll by avoiding trying to create a folder \\? when the // Improves os.MkdirAll by avoiding trying to create a folder `\\?` when the
// volume of a given extended length path does not exist. // volume of a given extended length path does not exist, and `\\?\UNC` when
// a network host name does not exist.
// //
// Based on source code from golang's os.MkdirAll // Based on source code from golang's os.MkdirAll
// (https://github.com/golang/go/blob/master/src/os/path.go) // (https://github.com/golang/go/blob/master/src/os/path.go)
@ -37,7 +38,6 @@ func MkdirAll(path string, perm os.FileMode) error {
} }
if i > 0 { if i > 0 {
path = path[:i] path = path[:i]
if path == filepath.VolumeName(path) { if path == filepath.VolumeName(path) {
// Make reference to a drive's root directory include the trailing slash. // Make reference to a drive's root directory include the trailing slash.
// In extended-length form without trailing slash ("\\?\C:"), os.Stat // In extended-length form without trailing slash ("\\?\C:"), os.Stat
@ -53,6 +53,7 @@ func MkdirAll(path string, perm os.FileMode) error {
j-- j--
} }
if j > 1 { if j > 1 {
if path[:j-1] != `\\?\UNC` {
// Create parent. // Create parent.
err = MkdirAll(path[:j-1], perm) err = MkdirAll(path[:j-1], perm)
if err != nil { if err != nil {
@ -61,6 +62,7 @@ func MkdirAll(path string, perm os.FileMode) error {
} }
} }
} }
}
// Parent now exists; invoke Mkdir and use its result. // Parent now exists; invoke Mkdir and use its result.
err = os.Mkdir(path, perm) err = os.Mkdir(path, perm)

View File

@ -128,3 +128,21 @@ func TestMkdirAllOnUnusedDrive(t *testing.T) {
errormsg = fmt.Sprintf("mkdir \\\\?\\%s\\: The system cannot find the path specified.", path) errormsg = fmt.Sprintf("mkdir \\\\?\\%s\\: The system cannot find the path specified.", path)
checkMkdirAllSubdirs(t, `\\?\`+path, false, errormsg) checkMkdirAllSubdirs(t, `\\?\`+path, false, errormsg)
} }
// Testing paths on unknown network host
// This is an additional difference from golang's os.MkdirAll. With our
// first fix, stopping it from recursing extended-length paths down to
// the "\\?" prefix, it would now stop at `\\?\UNC`, because that is what
// filepath.VolumeName returns (which is wrong, that is not a volume name!),
// and still return a nonifnromative error:
// "mkdir \\?\UNC\\: The filename, directory name, or volume label syntax is incorrect."
// Our version stops the recursion at level before this, and reports:
// "mkdir \\?\UNC\0.0.0.0: The specified path is invalid."
func TestMkdirAllOnUnusedNetworkHost(t *testing.T) {
path := `\\0.0.0.0\share`
errormsg := fmt.Sprintf("mkdir %s\\: The format of the specified network name is invalid.", path)
checkMkdirAllSubdirs(t, path, false, errormsg)
path = `\\?\UNC\0.0.0.0\share`
errormsg = `mkdir \\?\UNC\0.0.0.0: The specified path is invalid.`
checkMkdirAllSubdirs(t, path, false, errormsg)
}