-
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
Invalid UnixFileMode value when using the TarFile API #77096
Comments
Tagging subscribers to this area: @dotnet/area-system-io Issue DetailsDescriptionI'm trying to exact a tar file into a folder, and the tar file may contains folders and files, when I try to use the
Reproduction Stepsvar tmpDirPath = Path.Combine(TmpPath, Guid.NewGuid().ToString("N"));
await var fs = File.OpenRead(@"xx.tar.gz");
await using var decompressStream = new GZipStream(fs, CompressionMode.Decompress);
await TarFile.ExtractToDirectoryAsync(decompressStream, tmpDirPath, true); Expected behaviorWork as normal Actual behaviorException as before Regression?No response Known WorkaroundsNo response Configuration.NET 7 RC2 Other informationNo response
|
Is it possible to share a tar file that reproduces this? |
Sure, attached, thanks for the help |
Do you want to attach a debugger to find out what the unexpected UnixFileMode value is? Perhaps ideally it would be in the message. |
Sorry that it's a little hard for me to debug it, I had only Windows to debug, and it works well on Windows. And from the call stack, |
No problem, with the repro file they can easily do it. |
Here, the directory mode is 16877, but we should just discard the top four bits. This patch fixes the issue (and passes all the existing tests): --- a/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarEntry.cs
+++ b/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarEntry.cs
/// <remarks>The value in this field has no effect on Windows platforms.</remarks>
public UnixFileMode Mode
{
- get => (UnixFileMode)_header._mode;
+ get => (UnixFileMode)(_header._mode & 0xFFF); // mask to keep lower 12 bits and clear out the rest
set
{
- if ((int)value is < 0 or > 4095) // 4095 in decimal is 7777 in octal
+ if ((int)value is < 0 or > 0xFFF) // 0xFFF (4095 in decimal) is 7777 in octal
{ |
@am11 would you like to send a PR? |
@adamsitnik, we are using the same mask in the writer: runtime/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarWriter.Unix.cs Line 69 in 6dc9a74
First maybe confusing, but it is the least significant 12 bits)
It seems like other tools are writing mode with higher values, but we are constraining it. So I am not sure if we want to revisit it broadly or conservatively fix this bug. @carlossanlop and/or @tmds might also have opinions on this. |
The patch for
Probably the spec says this should store |
@WeihanLi could you provide more info on how did you create this tar.gz file? Please create a smaller one, with one or two directories and a hello world file; max size < 100 kb and if possible, send it via a PR to https://github.com/dotnet/runtime-assets. I extracted your .tar.gz using command line Also, if we remove |
The code splits in some places based on the |
I am testing with |
Good question. None of the other tools we're using seem to include the file type bits.
I don't see this. I get the same exception when doing
|
Hi @am11 , I got this file from the docker image layer, I'm trying to pull the docker image with the docker registry API |
My bad. I had a modification in Directory.Unix.cs, which was skipping the exception. Yes it is there on the main without GZipStream.
Thanks. Perhaps it is archive/tar golang package which generates such a tarball? I was able to reproduce it with a 20K image: $ docker pull hello-world
$ docker save hello-world -o hello-world.tar # uncompressed when saving a local image
# extract with your code without GZipStream step I'll open a PR in runtime-assets repo first so we can add test with the fix in this repo. |
Can you create an issue in their bugtracker? Since .NET writer filters out those bits, it seems we think the proper thing is to not include them. |
I am not sure if it belongs to producer of the package (https://github.com/golang/go) or its consumer (https://github.com/moby/moby). |
The issue will be fixed in the next version of Docker: moby/moby#44083. |
Description
I'm trying to exact a tar file into a folder, and the tar file may contains folders and files, when I try to use the
TarFile.ExtractToDirectory
API, I got the error like follows, maybe I'm wrong on using the APIReproduction Steps
Expected behavior
Work as normal
Actual behavior
Exception as before
Regression?
No response
Known Workarounds
No response
Configuration
.NET 7 RC2
CentOS 7
Other information
Works well on Windows but not on CentOS
The text was updated successfully, but these errors were encountered: