diff options
Diffstat (limited to 'src/syscall')
| -rw-r--r-- | src/syscall/syscall_windows.go | 24 | ||||
| -rw-r--r-- | src/syscall/ztypes_windows.go | 1 |
2 files changed, 23 insertions, 2 deletions
diff --git a/src/syscall/syscall_windows.go b/src/syscall/syscall_windows.go index e13d6e2dd5..f4f8f3ad09 100644 --- a/src/syscall/syscall_windows.go +++ b/src/syscall/syscall_windows.go @@ -1024,11 +1024,31 @@ func Readlink(path string, buf []byte) (n int, err error) { case IO_REPARSE_TAG_SYMLINK: data := (*symbolicLinkReparseBuffer)(unsafe.Pointer(&rdb.reparseBuffer)) p := (*[0xffff]uint16)(unsafe.Pointer(&data.PathBuffer[0])) - s = UTF16ToString(p[data.PrintNameOffset/2 : (data.PrintNameLength-data.PrintNameOffset)/2]) + s = UTF16ToString(p[data.SubstituteNameOffset/2 : (data.SubstituteNameOffset+data.SubstituteNameLength)/2]) + if data.Flags&_SYMLINK_FLAG_RELATIVE == 0 { + if len(s) >= 4 && s[:4] == `\??\` { + s = s[4:] + switch { + case len(s) >= 2 && s[1] == ':': // \??\C:\foo\bar + // do nothing + case len(s) >= 4 && s[:4] == `UNC\`: // \??\UNC\foo\bar + s = `\\` + s[4:] + default: + // unexpected; do nothing + } + } else { + // unexpected; do nothing + } + } case _IO_REPARSE_TAG_MOUNT_POINT: data := (*mountPointReparseBuffer)(unsafe.Pointer(&rdb.reparseBuffer)) p := (*[0xffff]uint16)(unsafe.Pointer(&data.PathBuffer[0])) - s = UTF16ToString(p[data.PrintNameOffset/2 : (data.PrintNameLength-data.PrintNameOffset)/2]) + s = UTF16ToString(p[data.SubstituteNameOffset/2 : (data.SubstituteNameOffset+data.SubstituteNameLength)/2]) + if len(s) >= 4 && s[:4] == `\??\` { // \??\C:\foo\bar + s = s[4:] + } else { + // unexpected; do nothing + } default: // the path is not a symlink or junction but another type of reparse // point diff --git a/src/syscall/ztypes_windows.go b/src/syscall/ztypes_windows.go index 8c2e19653a..1fb6f5c29f 100644 --- a/src/syscall/ztypes_windows.go +++ b/src/syscall/ztypes_windows.go @@ -1116,4 +1116,5 @@ const ( _IO_REPARSE_TAG_MOUNT_POINT = 0xA0000003 IO_REPARSE_TAG_SYMLINK = 0xA000000C SYMBOLIC_LINK_FLAG_DIRECTORY = 0x1 + _SYMLINK_FLAG_RELATIVE = 1 ) |
