Skip to content
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

os: Root ignores link type on Windows #71166

Open
neild opened this issue Jan 7, 2025 · 6 comments
Open

os: Root ignores link type on Windows #71166

neild opened this issue Jan 7, 2025 · 6 comments
Assignees
Labels
NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.

Comments

@neild
Copy link
Contributor

neild commented Jan 7, 2025

Windows makes a distinction between symlinks to a file and to a directory. A file link pointing to a directory cannot be traversed, nor can a directory link pointing to a file.

The os.Root type doesn't pay attention to link types when resolving files, however, and will follow links that Windows will not. It probably should behave consistently with the rest of the OS.

(See also #71165, which is the same issue in path/filepath.EvalSymlinks.)

@neild neild self-assigned this Jan 7, 2025
@neild
Copy link
Contributor Author

neild commented Jan 7, 2025

/cc @qmuntal

@gabyhelp
Copy link

gabyhelp commented Jan 7, 2025

Related Issues

(Emoji vote if this was helpful or unhelpful; more detailed feedback welcome in this discussion.)

@neild
Copy link
Contributor Author

neild commented Jan 7, 2025

Open question: How do you tell what kind of link an IO_REPARSE_TAG_SYMLINK reparse point is? I don't see anything in the reparse buffer that identifies it.

@qmuntal
Copy link
Member

qmuntal commented Jan 8, 2025

Open question: How do you tell what kind of link an IO_REPARSE_TAG_SYMLINK reparse point is? I don't see anything in the reparse buffer that identifies it.

We already know if an stat'ed symbolic links points to a directory, as we get this information in here:

var d syscall.ByHandleFileInformation
err = syscall.GetFileInformationByHandle(h, &d)
.

That problem is that FileInfo.Mode() doesn't set the ModeDir bit for symbolic links, so it difficult to know whether a symbolic link points to a directory or not:

go/src/os/types_windows.go

Lines 193 to 195 in 39f2032

if !fs.isReparseTagNameSurrogate() {
if fs.FileAttributes&syscall.FILE_ATTRIBUTE_DIRECTORY != 0 {
m |= ModeDir | 0111

What does Unix does in this case? Does it set the S_ISDIR?

@ianlancetaylor
Copy link
Member

In Unix a symbolic link is just a name forwarder. There is no difference between a link to a file and a link to a directory, and in fact you can change the destination from a file to a directory, or vice-versa, without affecting the symbolic link. So, no, a symbolic link will never have S_ISDIR set.

@neild
Copy link
Contributor Author

neild commented Jan 8, 2025

To make things more confusing:

  • link is a file link to dir.
  • dir is a directory.
  • dir\file is a file.

With this setup:

  • os.Open("link") fails as expected (file link to directory)
  • os.Open(`link\file`) opens dir\file successfully.

I don't know why this is. From the command line, type link\file fails as expected.

@seankhliao seankhliao added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Jan 9, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Projects
None yet
Development

No branches or pull requests

5 participants