-
Notifications
You must be signed in to change notification settings - Fork 18k
path/filepath: Walk on very long paths fails on Windows #21782
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
This seems similar to #20829. Perhaps there's another part of the standard library that needs this fix for long paths. |
This fails in os.Lstat(path), and path is relative path here. The os.Lstat is using os.fixLongPath, which has been created just for such purpose. But os.fixLongPath does not handle relative paths, and for a good reason - relative paths cannot be longer than 255 characters (see https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx#maxpath for details). I do not know how to fix this. Perhaps @quentinmit has some suggestions - he wrote os.fixLongPath. Alex |
I'm not sure, if this is possible, but i think os.Lstat returns the same value for absolute and relative paths. Is that correct? If so, why not convert all paths to absolute paths (e.g. with filepath.Abs) in os.Lstat on windows before using the syscall? |
Maybe we'll do that. I am not sure yet. Alex |
As a short feedback: I implemented a simple filesystem abstraction based on afero (https://github.com/spf13/afero) and the use filepath.Abs did the job for me. I used following logic: Why 200 chars, not 255? The problem is, that in later testing i noticed, that there errors occurred with some paths lower than 227 chars, so i corrected it down to 200. Would be nice to know the exact bound, but i didn't find out. The path with less than 255 chars, which caused the first error was: absolute: |
Unfortunately, it's very nontrivial to convert relative paths to absolute paths on Windows. I already went down that road and gave up on trying to make it work. If you need to Walk on long paths, you should just call Walk with an absolute path. I believe everything inside Walk should work correctly in that case. |
I already fixed it and for me it is working prepending a \\?\. You said that filepath.Abs only will work for short paths. In my case it does work perfectly with long paths. I'm not saying it is working in every case, but for now i did not find a path (including some node modules directories), that did not work. Code sample (taken from my project https://github.com/sandreas/graft/blob/master/filesystem/osfs_windows.go):
|
@quentinmit I just tried to test syscall.FullPath:
and it seems to be working. It works on both Windows 10 and Windows XP. Alex |
@gopherbot add "help wanted" |
@quentinmit what do you think of making os.fixLongPath() return an error for a path over the max length that doesn't start with EDIT: this says we can prepend cc @iwdgo |
@networkimprov |
@sandreas, according to #21782 (comment) syscall.FullPath doesn't prefix paths on Windows with Your file is missing |
You're absolutely right... The code i posted has (accidentally) not been tested on a windows system, where it would belong to - so it is incomplete. I'm sorry that this did not help. |
I've suggested a fix in #36375 (comment). Both that issue and this one should be fixed in the same CL. |
Change https://golang.org/cl/263538 mentions this issue: |
Change https://golang.org/cl/291291 mentions this issue: |
I would like to mention a highly opinonated article about this topic: https://fasterthanli.me/articles/i-want-off-mr-golangs-wild-ride I would suggest a |
Windows 10 >= 1607 allows CreateFile and friends to use long paths if bit 0x80 of the PEB's BitField member is set. In time this means we'll be able to entirely drop our long path hacks, which have never really worked right (see bugs below). Until that point, we'll simply have things working well on recent Windows. Updates #41734. Updates #21782. Updates #36375. Change-Id: I765de6ea4859dd4e4b8ca80af7f337994734118e Reviewed-on: https://go-review.googlesource.com/c/go/+/291291 Trust: Jason A. Donenfeld <[email protected]> Run-TryBot: Jason A. Donenfeld <[email protected]> TryBot-Result: Go Bot <[email protected]> Reviewed-by: Brad Fitzpatrick <[email protected]>
Issue was probably solved with #20829 and maybe later changes around
Issue seems solved. |
Change https://go.dev/cl/574695 mentions this issue: |
Change https://go.dev/cl/607437 mentions this issue: |
CL 574695 added caching the os.Chdir argument for Windows, and used the cached value to assess the length of the current working directory in addExtendedPrefix (used by fixLongPath). It did not take into account that Chdir can accept relative paths, and thus the pathLength calculation in addExtendedPrefix can be wrong. Let's only cache the os.Chdir argument if it's absolute, and clean the cache otherwise, thus improving the correctness of fixLongPath. For #41734 For #21782 For #36375 Change-Id: Ie24a5ed763a7aacc310666d2e4cbb8e298768670 Reviewed-on: https://go-review.googlesource.com/c/go/+/607437 Reviewed-by: Ian Lance Taylor <[email protected]> Reviewed-by: Alex Brainman <[email protected]> Reviewed-by: Damien Neil <[email protected]> Auto-Submit: Ian Lance Taylor <[email protected]> Reviewed-by: Quim Muntal <[email protected]> Reviewed-by: Cherry Mui <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]>
Please answer these questions before submitting your issue. Thanks!
What version of Go are you using (
go version
)?1.9
Does this issue reproduce with the latest release?
yes
What operating system and processor architecture are you using (
go env
)?set GOARCH=amd64
set GOBIN=
set GOEXE=.exe
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GOOS=windows
set GOPATH=C:\Users\mediacenter\go
set GORACE=
set GOROOT=C:\Go
set GOTOOLDIR=C:\Go\pkg\tool\windows_amd64
set GCCGO=gccgo
set CC=gcc
set GOGCCFLAGS=-m64 -mthreads -fmessage-length=0
set CXX=g++
set CGO_ENABLED=1
set CGO_CFLAGS=-g -O2
set CGO_CPPFLAGS=
set CGO_CXXFLAGS=-g -O2
set CGO_FFLAGS=-g -O2
set CGO_LDFLAGS=-g -O2
set PKG_CONFIG=pkg-config
What did you do?
Executing the sample code on a current windows 10 machine fails with an error - seems that running filepath.Walk on very long paths fails on windows in general.
Sample code, which works on play: https://play.golang.org/p/wMS5gti4SD
But it DOES NOT WORK on windows systems!
What did you expect to see?
correctly walk over..../package.json
What did you see instead?
ERROR ON PATH node_modules\babel-preset-es2015\node_modules\babel-plugin-transform-es2015-block-scoping\node_modules\babel-traverse\node_modules\babel-code-frame\node_modules\chalk\node_modules\strip-ansi\node_modules\ansi-regex\package.json: GetFileAttributesEx node_modules\babel-preset-es2015\node_modules\babel-plugin-transform-es2015-block-scoping\node_modules\babel-traverse\node_modules\babel-code-frame\node_modules\chalk\node_modules\strip-ansi\node_modules\ansi-regex\package.json: Das System kann den angegebenen Pfad nicht finden.
Can anyone confirm this behaviour?
The text was updated successfully, but these errors were encountered: