Description
What version of Go are you using (go version
)?
go version go1.8.3 windows/amd64
What operating system and processor architecture are you using (go env
)?
GOOS=windows
GOARCH=amd64
What did you do?
os.Chmod
returns an unexpected error when passed a path that is longer than MAX_PATH
(260) characters.
What did you expect to see?
Similar behavior to other file functions in os
. Calling os.fixLongPath
on the path before passing the pointer to GetFileAttributesW
and SetFileAttributesW
.
231aa9d fixed the issue with long paths (>=260 chars) by introducing a new function, os.fixLongPath
, which converts the path to an extended-length path on Windows.
What did you see instead?
chmod C:\Users\ibrahim\go\src\github.com\ibrasho\deptest\vendor\github.com\prometheus\procfs\sysfs\fixtures.src\devices\pci0000_@colon@_00\0000_@colon@_00_@colon@_0d.0\ata4\host3\target3_@colon@_0_@colon@_0\3_@colon@_0_@colon@_0_@colon@_0\block\sdb\bcache\dirty_data: The system cannot find the path specified.
Applying the same logic from os.fixLongPath
before passing the path to os.Chmod
resolves this issue.
Activity
ibrasho commentedon Jun 28, 2017
I've found this issue while investigating golang/dep#774.
I've found multiple other file related functions implemented outside
os
(insyscall
) that are also affected. According to Naming Files, Paths and Namespaces on MSDN:Here is a list of possible occurrences of this issue (where these functions were called without running the path through
os.fixLongPath
first:syscall.Open
: callsCreateFileW
syscall.Chdir
: callsSetCurrentDirectoryW
syscall.Mkdir
: callsCreateDirectoryW
syscall.Rmdir
: callsRemoveDirectoryW
syscall.Unlink
: callsDeleteFileW
syscall.Rename
: callsMoveFileW
(os.Rename
works fine)syscall.UtimesNano
: callsCreateFileW
syscall.Chmod
: callsGetFileAttributesW
andSetFileAttributesW
syscall.FullPath
: callsGetFullPathNameW
It could possibly occur in
os.SameFile
since it ends up callingos.*fileStat.loadFileId
which attemptsCreateFileW
without usingos.fixLongPath
.bradfitz commentedon Jun 28, 2017
I think we previously decided that we aren't adding magic UNC path mangling to the low-level syscall package. If users are using syscall, they can read MSDN docs.
Let's keep this bug specifically about Chmod.
ibrasho commentedon Jun 28, 2017
I'm can work on a fix. But I've some questions:
Since these functions are implemented inonly 2 of them need fixing.syscall
, how are they exposed inos
? Can we just create a wrapper around them inos
that fixes this bug?syscall.Rename
: is duplicated ininternal/syscall/windows.Rename
. Is there a reason?edit: Actually, there is a difference.
internal/syscall/windows.Rename
replaces the destination if it exists, whilesyscall.Rename
fails in that case.ibrasho commentedon Jun 28, 2017
@bradfitz
In that case, evenI'll submit a CL in a couple of minutes.os.Remove
needs the same fix.Edit: my mistake. I was reading the wrong file. Only
os.Chmod
is broken.bradfitz commentedon Jun 28, 2017
Remove was already done in 231aa9d. I see:
And Chmod should be just:
gopherbot commentedon Jun 28, 2017
CL https://golang.org/cl/47010 mentions this issue.