summaryrefslogtreecommitdiff
path: root/libgo/go/path/filepath/symlink_windows.go
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/go/path/filepath/symlink_windows.go')
-rw-r--r--libgo/go/path/filepath/symlink_windows.go29
1 files changed, 26 insertions, 3 deletions
diff --git a/libgo/go/path/filepath/symlink_windows.go b/libgo/go/path/filepath/symlink_windows.go
index 243352819e0..bb05aabc924 100644
--- a/libgo/go/path/filepath/symlink_windows.go
+++ b/libgo/go/path/filepath/symlink_windows.go
@@ -22,7 +22,7 @@ func normVolumeName(path string) string {
return strings.ToUpper(volume)
}
-// normBase retruns the last element of path.
+// normBase returns the last element of path with correct case.
func normBase(path string) (string, error) {
p, err := syscall.UTF16PtrFromString(path)
if err != nil {
@@ -40,7 +40,24 @@ func normBase(path string) (string, error) {
return syscall.UTF16ToString(data.FileName[:]), nil
}
-func toNorm(path string, base func(string) (string, error)) (string, error) {
+// baseIsDotDot returns whether the last element of path is "..".
+// The given path should be 'Clean'-ed in advance.
+func baseIsDotDot(path string) bool {
+ i := strings.LastIndexByte(path, Separator)
+ return path[i+1:] == ".."
+}
+
+// toNorm returns the normalized path that is guranteed to be unique.
+// It should accept the following formats:
+// * UNC paths (e.g \\server\share\foo\bar)
+// * absolute paths (e.g C:\foo\bar)
+// * relative paths begin with drive letter (e.g C:foo\bar, C:..\foo\bar, C:.., C:.)
+// * relative paths begin with '\' (e.g \foo\bar)
+// * relative paths begin without '\' (e.g foo\bar, ..\foo\bar, .., .)
+// The returned normalized path will be in the same form (of 5 listed above) as the input path.
+// If two paths A and B are indicating the same file with the same format, toNorm(A) should be equal to toNorm(B).
+// The normBase parameter should be equal to the normBase func, except for in tests. See docs on the normBase func.
+func toNorm(path string, normBase func(string) (string, error)) (string, error) {
if path == "" {
return path, nil
}
@@ -58,7 +75,13 @@ func toNorm(path string, base func(string) (string, error)) (string, error) {
var normPath string
for {
- name, err := base(volume + path)
+ if baseIsDotDot(path) {
+ normPath = path + `\` + normPath
+
+ break
+ }
+
+ name, err := normBase(volume + path)
if err != nil {
return "", err
}