lib/file: fix MkdirAll after go1.21.4 stdlib update

In ths security related issue the go1.21.4 stdlib changed the parsing
of volume names on Windows.

https://github.com/golang/go/issues/63713

This had the consequences of breaking the MkdirAll tests which were
looking for specific error messages which changed and using invalid
paths.

In particular under go1.21.3:

    filepath.VolumeName(`\\?\C:`) == `\\?\C:`

But under go1.21.4 it is:

    filepath.VolumeName(`\\?\C:`) == `\\?`

The path `\\?\C:` isn't actually a valid Windows path. I reported this
as a FYI bug upstream - I'm not expecting it to be fixed.

See: https://github.com/golang/go/issues/64101
This commit is contained in:
Nick Craig-Wood 2023-11-13 15:19:22 +00:00
parent 831d1df67f
commit acf1e2df84
2 changed files with 7 additions and 6 deletions

View File

@ -53,7 +53,7 @@ func MkdirAll(path string, perm os.FileMode) error {
j-- j--
} }
if j > 1 { if j > 1 {
if path[:j-1] != `\\?\UNC` { if path[:j-1] != `\\?\UNC` && path[:j-1] != `\\?` {
// Create parent. // Create parent.
err = MkdirAll(path[:j-1], perm) err = MkdirAll(path[:j-1], perm)
if err != nil { if err != nil {

View File

@ -89,7 +89,7 @@ func checkMkdirAll(t *testing.T, path string, valid bool, errormsgs ...string) {
ok = true ok = true
} }
} }
assert.True(t, ok, err.Error()) assert.True(t, ok, fmt.Sprintf("Error message '%v' didn't match any of %v", err, errormsgs))
} }
} }
@ -114,7 +114,7 @@ func TestMkdirAllOnDrive(t *testing.T) {
checkMkdirAll(t, drive, true, "") checkMkdirAll(t, drive, true, "")
checkMkdirAll(t, drive+`\`, true, "") checkMkdirAll(t, drive+`\`, true, "")
checkMkdirAll(t, `\\?\`+drive, true, "") // checkMkdirAll(t, `\\?\`+drive, true, "") - this isn't actually a Valid Windows path - this test used to work under go1.21.3 but fails under go1.21.4
checkMkdirAll(t, `\\?\`+drive+`\`, true, "") checkMkdirAll(t, `\\?\`+drive+`\`, true, "")
checkMkdirAllSubdirs(t, path, true, "") checkMkdirAllSubdirs(t, path, true, "")
checkMkdirAllSubdirs(t, `\\?\`+path, true, "") checkMkdirAllSubdirs(t, `\\?\`+path, true, "")
@ -129,10 +129,11 @@ func TestMkdirAllOnDrive(t *testing.T) {
// "mkdir \\?\A:\: The system cannot find the path specified." // "mkdir \\?\A:\: The system cannot find the path specified."
func TestMkdirAllOnUnusedDrive(t *testing.T) { func TestMkdirAllOnUnusedDrive(t *testing.T) {
path := unusedDrive(t) path := unusedDrive(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)
errormsg = fmt.Sprintf("mkdir \\\\?\\%s\\: The system cannot find the path specified.", path) errormsg1 := fmt.Sprintf(`mkdir \\?\%s\: The system cannot find the path specified.`, path) // pre go1.21.4
checkMkdirAllSubdirs(t, `\\?\`+path, false, errormsg) errormsg2 := fmt.Sprintf(`mkdir \\?\%s: The system cannot find the file specified.`, path) // go1.21.4 and after
checkMkdirAllSubdirs(t, `\\?\`+path, false, errormsg1, errormsg2)
} }
// Testing paths on unknown network host // Testing paths on unknown network host