mirror of
https://github.com/golang/go
synced 2024-11-14 15:10:54 -07:00
7a1347a1a1
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>
77 lines
2.3 KiB
Go
77 lines
2.3 KiB
Go
// Copyright 2016 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package os_test
|
|
|
|
import (
|
|
"io/ioutil"
|
|
"os"
|
|
"strings"
|
|
"syscall"
|
|
"testing"
|
|
)
|
|
|
|
func TestFixLongPath(t *testing.T) {
|
|
// 248 is long enough to trigger the longer-than-248 checks in
|
|
// fixLongPath, but short enough not to make a path component
|
|
// longer than 255, which is illegal on Windows. (which
|
|
// doesn't really matter anyway, since this is purely a string
|
|
// function we're testing, and it's not actually being used to
|
|
// do a system call)
|
|
veryLong := "l" + strings.Repeat("o", 248) + "ng"
|
|
for _, test := range []struct{ in, want string }{
|
|
// Short; unchanged:
|
|
{`C:\short.txt`, `C:\short.txt`},
|
|
{`C:\`, `C:\`},
|
|
{`C:`, `C:`},
|
|
// The "long" substring is replaced by a looooooong
|
|
// string which triggers the rewriting. Except in the
|
|
// cases below where it doesn't.
|
|
{`C:\long\foo.txt`, `\\?\C:\long\foo.txt`},
|
|
{`C:/long/foo.txt`, `\\?\C:\long\foo.txt`},
|
|
{`C:\long\foo\\bar\.\baz\\`, `\\?\C:\long\foo\bar\baz`},
|
|
{`\\unc\path`, `\\unc\path`},
|
|
{`long.txt`, `long.txt`},
|
|
{`C:long.txt`, `C:long.txt`},
|
|
{`c:\long\..\bar\baz`, `c:\long\..\bar\baz`},
|
|
{`\\?\c:\long\foo.txt`, `\\?\c:\long\foo.txt`},
|
|
{`\\?\c:\long/foo.txt`, `\\?\c:\long/foo.txt`},
|
|
} {
|
|
in := strings.Replace(test.in, "long", veryLong, -1)
|
|
want := strings.Replace(test.want, "long", veryLong, -1)
|
|
if got := os.FixLongPath(in); got != want {
|
|
got = strings.Replace(got, veryLong, "long", -1)
|
|
t.Errorf("fixLongPath(%q) = %q; want %q", test.in, got, test.want)
|
|
}
|
|
}
|
|
}
|
|
|
|
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)
|
|
}
|
|
}
|