]> Cypherpunks repositories - gostls13.git/commitdiff
os: make MkdirAll support path in extended-length form
authorMansour Rahimi <rahimi.mnr@gmail.com>
Sun, 28 Jan 2018 21:19:13 +0000 (22:19 +0100)
committerAlex Brainman <alex.brainman@gmail.com>
Sun, 18 Feb 2018 03:44:53 +0000 (03:44 +0000)
Calling MkdirAll on paths in extended-length form (\\?\-prefixed)
failed.

MkdirAll calls itself recursively with parent directory of given path in
its parameter. It finds parent directory by looking for delimiter in
the path, and taking the left part. When path is in extended-length form,
it finds empty path at the end.

Here is a sample of path in extended-length form:
\\?\c:\foo\bar

This change fixes that by passing trailing path separator to MkdirAll (so
it works for path like \\?\c:\).

Fixes #22230

Change-Id: I363660b262588c5382ea829773d3b6005ab8df3c
Reviewed-on: https://go-review.googlesource.com/86295
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
Run-TryBot: Alex Brainman <alex.brainman@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/os/path.go
src/os/path_windows_test.go

index eb996e5fb9174b9aad4f45b3a795d89f7b9cedf0..ec6a7938b2b856848b19cb638ab409763bbe8e53 100644 (file)
@@ -39,8 +39,10 @@ func MkdirAll(path string, perm FileMode) error {
        }
 
        if j > 1 {
-               // Create parent
-               err = MkdirAll(path[0:j-1], perm)
+               // Create parent.
+               // Pass trailing path separator to MkdirAll, so our
+               // algorithm works for paths, like \\?\c:\
+               err = MkdirAll(path[0:j], perm)
                if err != nil {
                        return err
                }
index cce0bdd522dc2fc43328a951efda97eaa1225693..00a3e63bf3ceca6963711734b60159a9c97ae450 100644 (file)
@@ -5,8 +5,10 @@
 package os_test
 
 import (
+       "io/ioutil"
        "os"
        "strings"
+       "syscall"
        "testing"
 )
 
@@ -44,3 +46,31 @@ func TestFixLongPath(t *testing.T) {
                }
        }
 }
+
+func TestMkdirAllExtendedLength(t *testing.T) {
+       tmpDir, err := ioutil.TempDir("", "TestMkdirAllExtendedLength")
+       if err != nil {
+               t.Fatal(err)
+       }
+       defer os.RemoveAll(tmpDir)
+
+       const prefix = `\\?\`
+       if len(tmpDir) < 4 || tmpDir[:4] != prefix {
+               fullPath, err := syscall.FullPath(tmpDir)
+               if err != nil {
+                       t.Fatalf("FullPath(%q) fails: %v", tmpDir, err)
+               }
+               tmpDir = prefix + fullPath
+       }
+       path := tmpDir + `\dir\`
+       err = os.MkdirAll(path, 0777)
+       if err != nil {
+               t.Fatalf("MkdirAll(%q) failed: %v", path, err)
+       }
+
+       path = path + `.\dir2`
+       err = os.MkdirAll(path, 0777)
+       if err == nil {
+               t.Fatalf("MkdirAll(%q) should have failed, but did not", path)
+       }
+}