diff options
Diffstat (limited to 'libgo/go/path/filepath')
-rw-r--r-- | libgo/go/path/filepath/path_test.go | 24 | ||||
-rw-r--r-- | libgo/go/path/filepath/path_windows.go | 4 | ||||
-rw-r--r-- | libgo/go/path/filepath/symlink_windows.go | 40 |
3 files changed, 63 insertions, 5 deletions
diff --git a/libgo/go/path/filepath/path_test.go b/libgo/go/path/filepath/path_test.go index 87cb5e55308..b8766588cf5 100644 --- a/libgo/go/path/filepath/path_test.go +++ b/libgo/go/path/filepath/path_test.go @@ -814,6 +814,7 @@ type VolumeNameTest struct { var volumenametests = []VolumeNameTest{ {`c:/foo/bar`, `c:`}, {`c:`, `c:`}, + {`2:`, ``}, {``, ``}, {`\\\host`, ``}, {`\\\host\`, ``}, @@ -845,3 +846,26 @@ func TestVolumeName(t *testing.T) { } } } + +func TestDriveLetterInEvalSymlinks(t *testing.T) { + if runtime.GOOS != "windows" { + return + } + wd, _ := os.Getwd() + if len(wd) < 3 { + t.Errorf("Current directory path %q is too short", wd) + } + lp := strings.ToLower(wd) + up := strings.ToUpper(wd) + flp, err := filepath.EvalSymlinks(lp) + if err != nil { + t.Fatalf("EvalSymlinks(%q) failed: %q", lp, err) + } + fup, err := filepath.EvalSymlinks(up) + if err != nil { + t.Fatalf("EvalSymlinks(%q) failed: %q", up, err) + } + if flp != fup { + t.Errorf("Results of EvalSymlinks do not match: %q and %q", flp, fup) + } +} diff --git a/libgo/go/path/filepath/path_windows.go b/libgo/go/path/filepath/path_windows.go index 1d1d23bfe7c..3dcd0302195 100644 --- a/libgo/go/path/filepath/path_windows.go +++ b/libgo/go/path/filepath/path_windows.go @@ -35,9 +35,7 @@ func VolumeName(path string) (v string) { } // with drive letter c := path[0] - if path[1] == ':' && - ('0' <= c && c <= '9' || 'a' <= c && c <= 'z' || - 'A' <= c && c <= 'Z') { + if path[1] == ':' && ('a' <= c && c <= 'z' || 'A' <= c && c <= 'Z') { return path[:2] } // is it UNC diff --git a/libgo/go/path/filepath/symlink_windows.go b/libgo/go/path/filepath/symlink_windows.go index afa88bfe876..1ee939928e9 100644 --- a/libgo/go/path/filepath/symlink_windows.go +++ b/libgo/go/path/filepath/symlink_windows.go @@ -8,7 +8,24 @@ import ( "syscall" ) -func evalSymlinks(path string) (string, error) { +func toShort(path string) (string, error) { + p := syscall.StringToUTF16(path) + b := p // GetShortPathName says we can reuse buffer + n, err := syscall.GetShortPathName(&p[0], &b[0], uint32(len(b))) + if err != nil { + return "", err + } + if n > uint32(len(b)) { + b = make([]uint16, n) + n, err = syscall.GetShortPathName(&p[0], &b[0], uint32(len(b))) + if err != nil { + return "", err + } + } + return syscall.UTF16ToString(b), nil +} + +func toLong(path string) (string, error) { p := syscall.StringToUTF16(path) b := p // GetLongPathName says we can reuse buffer n, err := syscall.GetLongPathName(&p[0], &b[0], uint32(len(b))) @@ -23,5 +40,24 @@ func evalSymlinks(path string) (string, error) { } } b = b[:n] - return Clean(syscall.UTF16ToString(b)), nil + return syscall.UTF16ToString(b), nil +} + +func evalSymlinks(path string) (string, error) { + p, err := toShort(path) + if err != nil { + return "", err + } + p, err = toLong(p) + if err != nil { + return "", err + } + // syscall.GetLongPathName does not change the case of the drive letter, + // but the result of EvalSymlinks must be unique, so we have + // EvalSymlinks(`c:\a`) == EvalSymlinks(`C:\a`). + // Make drive letter upper case. + if len(p) >= 2 && p[1] == ':' && 'a' <= p[0] && p[0] <= 'z' { + p = string(p[0]+'A'-'a') + p[1:] + } + return Clean(p), nil } |