From 377200591e68a863d02249244d445bfa49f6a0c2 Mon Sep 17 00:00:00 2001 From: Ross Smith II Date: Sun, 27 Oct 2024 08:08:38 -0700 Subject: [PATCH] fix(fs): fix directory junction handling (fixes #9775) (#9786) ### Purpose This fixes #9775. I also improved the comments as they were lacking. My apologies for introducing this bug. In summary, the bug was ``` mode = mode ^ (ModeSymlink | ModeIrregular) ``` didn't correctly reset those bits. This correctly resets them: ``` mode = mode &^ ModeSymlink &^ ModeIrregular ``` Tested and working in Windows 11 version 10.0.22631.4317. I didn't test in other versions, but I'm sure this is the only issue. --- lib/fs/basicfs_lstat_windows.go | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/fs/basicfs_lstat_windows.go b/lib/fs/basicfs_lstat_windows.go index de2f63280..1868880d1 100644 --- a/lib/fs/basicfs_lstat_windows.go +++ b/lib/fs/basicfs_lstat_windows.go @@ -67,7 +67,7 @@ type dirJunctFileInfo struct { func (fi *dirJunctFileInfo) Mode() os.FileMode { // Simulate a directory and not a symlink; also set the execute // bits so the directory can be traversed Unix-side. - return fi.FileInfo.Mode() ^ junctionPointModeMask | os.ModeDir | 0111 + return fi.FileInfo.Mode()&^junctionPointModeMask | os.ModeDir | 0111 } func (fi *dirJunctFileInfo) IsDir() bool { @@ -77,10 +77,13 @@ func (fi *dirJunctFileInfo) IsDir() bool { var junctionPointModeMask os.FileMode func init() { + // Per https://tip.golang.org/doc/go1.23#minor_library_changes + // In go1.22 (and go1.23 when GODEBUG=winsymlink=0) Windows' directory + // junctions (aka "mount points") always have ModeSymlink set. junctionPointModeMask = os.ModeSymlink if version.Compare(runtime.Version(), "go1.23") >= 0 { - // if GODEBUG=winsymlink=0, then we are in g1.22 mode so let's check for - // os.ModeSymlink as well, as it can't hurt. + // In go1.23 Windows' directory junctions always have ModeIrregular set + // (unless GODEBUG=winsymlink=0). junctionPointModeMask |= os.ModeIrregular } }