-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
Tar: Only treat reparse points marked as junctions or symlinks as actual tar symlinks #89102
Conversation
…stFileEx.cs for shared consumption.
… point is a junction or a symbolic link, in which case the filesystem object will be treated as a tar symbolic link. All other reparse points will be treated as regular files.
…specified format and consume it in TarWriter.Unix.cs and TarWriter.Windows.cs.
…um value for the specified format.
…ve, verify they are added as symbolic links entries.
Tagging subscribers to this area: @dotnet/area-system-formats-tar Issue DetailsThe current code only checks if it's a reparse point and adds the filesystem object as a symlink, which is wrong for many types of reparse points. Only those marked as junctions or symlinks should be treated as tar symlinks. I added a test to confirm that a junction is stored as symlink. I am unsure how to create other types of reparse points so I didn't add tests for that, but since those are rarer cases, I would prefer to tackle them separately if requested. cc @billfreist, thanks for reporting this. Fixes #82949
|
[InlineData(TarEntryFormat.Ustar)] | ||
[InlineData(TarEntryFormat.Pax)] | ||
[InlineData(TarEntryFormat.Gnu)] | ||
public void Add_Junction_As_SymbolicLink(TarEntryFormat format) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you run these tests without elevation? I think it's missing a can create symlinks condition. I've added them a few times when tests failed locally.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Starting with Windows 10 Insiders build 14972, symlinks can be created without needing to elevate the console as administrator. https://blogs.windows.com/windowsdeveloper/2016/12/02/symlinks-windows-10/
If we still have tests running older Windows versions, they should break in the CI.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Junctions are ancient, they don't require elevation AFAIK. They ran without problem in my local machine. The CI should also cry if something goes wrong.
This new test does not create symlinks in the disk by the way, it adds an entry to the tar archive as a symlink. The only thing that gets created in disk is the junction.
bool isDirectory = (attributes & FileAttributes.Directory) != 0; | ||
|
||
Interop.Kernel32.WIN32_FIND_DATA data = default; | ||
Interop.Kernel32.GetFindData(fullPath, isDirectory, ignoreAccessDenied: false, ref data); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this be called only when the file is a reparse point?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right.
if (data.dwReserved0 is Interop.Kernel32.IOReparseOptions.IO_REPARSE_TAG_SYMLINK or | ||
Interop.Kernel32.IOReparseOptions.IO_REPARSE_TAG_MOUNT_POINT) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks like another data point in favor of having an API for ReparseTags #1908.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed.
You can test IO_REPARSE_TAG_APPEXECLINK by trying to archive one file with such ReparseTag:
|
Thanks @jozkee, I forgot about that. I wrote a test that attempts to verify what happens when adding an AppExecLink. I reused the method that we have to retrieve the first AppExecLink from the WindowsApps folder. In my case, it's It seems that my current code would throw an IOException when FileStream attempts to create a file handle to it (see the callkstack below). Which means we can't treat AppExecLinks as regular files. I think for now, we should just throw an IOException on the Tar code when we encounter an unsupported ReparsePoint. There might be a way to crack open an AppExecLink, retrieve some internal information it holds, and then store it in the DataStream, but we don't have an actual entry type to indicate this is an AppExecLink file, which differs from a regular file and from a symlink. So if the user generates a tar archive containing one of these, then tries to extract it, it will be extracted as something that it is not. Thoughts?
|
src/libraries/System.Formats.Tar/tests/TarWriter/TarWriter.WriteEntry.File.Tests.Windows.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Formats.Tar/tests/TarWriter/TarWriter.WriteEntry.File.Tests.Windows.cs
Outdated
Show resolved
Hide resolved
...libraries/System.Formats.Tar/tests/TarWriter/TarWriter.WriteEntryAsync.File.Tests.Windows.cs
Outdated
Show resolved
Hide resolved
...libraries/System.Formats.Tar/tests/TarWriter/TarWriter.WriteEntryAsync.File.Tests.Windows.cs
Outdated
Show resolved
Hide resolved
@carlossanlop what's the next step to move this one forward? |
Make sure we have tests that confirm my changes are working, haven't been able to get back to it yet. Need to find a way to test adding a OneDrive cloud file. Maybe I could add manual tests. |
This pull request has been automatically marked |
This pull request will now be closed since it had been marked |
The current code only checks if it's a reparse point and adds the filesystem object as a symlink, which is wrong for many types of reparse points. Only those marked as junctions or symlinks should be treated as tar symlinks.
I added a test to confirm that a junction is stored as symlink. I am unsure how to create other types of reparse points so I didn't add tests for that, but since those are rarer cases, I would prefer to tackle them separately if requested.
cc @billfreist, thanks for reporting this.
Fixes #82949