From 3cc44f42397ca72a09788a7cf8e4e48fce9a4a65 Mon Sep 17 00:00:00 2001 From: Eric Date: Tue, 7 Jul 2020 16:58:24 +0200 Subject: [PATCH 1/2] Fixes #39786 --- src/os/file_windows.go | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/os/file_windows.go b/src/os/file_windows.go index cc695fd94c746a..37d222b490218f 100644 --- a/src/os/file_windows.go +++ b/src/os/file_windows.go @@ -402,6 +402,7 @@ func openSymlink(path string) (syscall.Handle, error) { // \??\C:\foo\bar into C:\foo\bar // \??\UNC\foo\bar into \\foo\bar // \??\Volume{abc}\ into C:\ +// \??\Volume{abc}\ into \\?\Volume{abc} if GetFinalPathNameByHandle(,,,VOLUME_NAME_DOS) returns PATH_NOT_FOUND (3) func normaliseLinkPath(path string) (string, error) { if len(path) < 4 || path[:4] != `\??\` { // unexpected path, return it as is @@ -431,8 +432,15 @@ func normaliseLinkPath(path string) (string, error) { defer syscall.CloseHandle(h) buf := make([]uint16, 100) + isVolumeNameGUID := false for { n, err := windows.GetFinalPathNameByHandle(h, &buf[0], uint32(len(buf)), windows.VOLUME_NAME_DOS) + if errors.Is(err, ErrNotExist) { + n, err = windows.GetFinalPathNameByHandle(h, &buf[0], uint32(len(buf)), windows.VOLUME_NAME_GUID) + if err == nil { + isVolumeNameGUID = true + } + } if err != nil { return "", err } @@ -443,7 +451,9 @@ func normaliseLinkPath(path string) (string, error) { } s = syscall.UTF16ToString(buf) if len(s) > 4 && s[:4] == `\\?\` { - s = s[4:] + if !isVolumeNameGUID { + s = s[4:] + } if len(s) > 3 && s[:3] == `UNC` { // return path like \\server\share\... return `\` + s[3:], nil From c22d0356040e26f4bbd4198e6622261b589322cf Mon Sep 17 00:00:00 2001 From: Eric Date: Sun, 12 Jul 2020 18:15:47 +0200 Subject: [PATCH 2/2] path/filepath: fix EvalSymLink documentation This documentation change is the best solution for EvalSymLinks short of deleting this API altogether. EvalSymLinks is not suitable on any operating system because it unconditionally undoes indirections without being aware of the problems that these indirections solve. This is a violation of the software engineering principle which states: > Any problem in software can be solved by adding another layer of indirection. --- src/path/filepath/path.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/path/filepath/path.go b/src/path/filepath/path.go index 26f183318923d8..2681d45c5d348a 100644 --- a/src/path/filepath/path.go +++ b/src/path/filepath/path.go @@ -230,6 +230,12 @@ func Ext(path string) string { // If path is relative the result will be relative to the current directory, // unless one of the components is an absolute symbolic link. // EvalSymlinks calls Clean on the result. +// Use of this function is unsuitable for applications. +// This function always resolves all links on path, but links introduce +// indirections that may solve problems that are not the concern of applications +// and of which applications should remain unaware unless they perform +// system administrative tasks on behalf of the user in which case they should +// resolve only those links that they create, manage and delete. func EvalSymlinks(path string) (string, error) { return evalSymlinks(path) }