tar extraction doesn't preserve file permissions #262

Open
opened 2026-01-29 22:09:12 +00:00 by claunia · 7 comments
Owner

Originally created by @MichaelJCompton on GitHub (Dec 6, 2017).

v0.18.2, netcoreapp2.0 on linux/mac,

tar contains

-rw-rw-r--  ... blaa.md
-rwxrwxrwx  ... blaa.sh

result of extraction is

-rw-r--r-- ... blaa.md
-rw-r--r--  ... blaa.sh

(PreserveAttributes option to ExtractionOptions not implemented)

Originally created by @MichaelJCompton on GitHub (Dec 6, 2017). v0.18.2, netcoreapp2.0 on linux/mac, tar contains ``` -rw-rw-r-- ... blaa.md -rwxrwxrwx ... blaa.sh ``` result of extraction is ``` -rw-r--r-- ... blaa.md -rw-r--r-- ... blaa.sh ``` (`PreserveAttributes` option to `ExtractionOptions` not implemented)
claunia added the enhancement label 2026-01-29 22:09:12 +00:00
Author
Owner

@adamhathcock commented on GitHub (Dec 7, 2017):

Applying file permissions is kind of out of scope. The file extraction methods are just convenience.

@adamhathcock commented on GitHub (Dec 7, 2017): Applying file permissions is kind of out of scope. The file extraction methods are just convenience.
Author
Owner

@pauldotknopf commented on GitHub (Apr 12, 2019):

I don't mind extracting the files myself, but there is currently no way to get what the file permissions should be.

I think they should at least be exposed in the TarHeader so that implementors can choose to use mode/user/group if they choose.

https://github.com/adamhathcock/sharpcompress/blob/master/src/SharpCompress/Common/Tar/Headers/TarHeader.cs#L121

@pauldotknopf commented on GitHub (Apr 12, 2019): I don't mind extracting the files myself, but there is currently no way to get what the file permissions *should* be. I think they should at least be exposed in the ```TarHeader``` so that implementors can choose to use mode/user/group if they choose. https://github.com/adamhathcock/sharpcompress/blob/master/src/SharpCompress/Common/Tar/Headers/TarHeader.cs#L121
Author
Owner

@adamhathcock commented on GitHub (Apr 13, 2019):

Sounds like a good PR to me :)

@adamhathcock commented on GitHub (Apr 13, 2019): Sounds like a good PR to me :)
Author
Owner

@Ryhon0 commented on GitHub (Apr 10, 2022):

5 years later, there seems to be code for reading the permissions but is commented out, using PreserveAttributes throws NotImplementedException.
If setting permissions is out of the scope, can we please get a delegate for setting permissions, just like we have for creating symlinks?
Since UNIX permissions might not apply for Windows, alternatively just make the permission properties public and let the developers handle it in the ExtractAllEntries loop

@Ryhon0 commented on GitHub (Apr 10, 2022): 5 years later, there seems to be code for reading the permissions but is commented out, using `PreserveAttributes` throws `NotImplementedException`. If setting permissions is out of the scope, can we please get a delegate for setting permissions, just like we have for creating symlinks? Since UNIX permissions might not apply for Windows, alternatively just make the permission properties public and let the developers handle it in the `ExtractAllEntries` loop
Author
Owner

@adamhathcock commented on GitHub (Apr 11, 2022):

Sounds like a good PR to me :)

@adamhathcock commented on GitHub (Apr 11, 2022): Sounds like a good PR to me :)
Author
Owner

@Ryhon0 commented on GitHub (Apr 11, 2022):

No idea if that is the correct way to implement it.
Can be tested with following code:

public static void Main()
{
	using (Stream stream = File.OpenRead("Tar.tar"))
	using (IReader reader = ReaderFactory.Open(stream))
	{
		int x = 0;
		while (reader.MoveToNextEntry())
		{
			var en = reader.Entry as TarEntry;
			Console.WriteLine($"{en.Key}\t" +
				$"{PermissionString(en.Mode)}\t" +
				$"{en.UserID}\t" +
				$"{en.GroupId}");
		}
	}
}

public static string PermissionString(long perms)
{
	const string ss = "drwxrwxrwx";
	const string ns = "----------";
	string s =  "";
	for(int i = 0; i < ss.Length; i++)
	{
		s += (perms & (1 << ss.Length - i - 1)) == 0 ? ns[i] : ss[i];
	}
	return s;
}
@Ryhon0 commented on GitHub (Apr 11, 2022): No idea if that is the correct way to implement it. Can be tested with following code: ```cs public static void Main() { using (Stream stream = File.OpenRead("Tar.tar")) using (IReader reader = ReaderFactory.Open(stream)) { int x = 0; while (reader.MoveToNextEntry()) { var en = reader.Entry as TarEntry; Console.WriteLine($"{en.Key}\t" + $"{PermissionString(en.Mode)}\t" + $"{en.UserID}\t" + $"{en.GroupId}"); } } } public static string PermissionString(long perms) { const string ss = "drwxrwxrwx"; const string ns = "----------"; string s = ""; for(int i = 0; i < ss.Length; i++) { s += (perms & (1 << ss.Length - i - 1)) == 0 ? ns[i] : ss[i]; } return s; } ```
Author
Owner

@adamhathcock commented on GitHub (Apr 11, 2022):

Thanks for the PR!

@adamhathcock commented on GitHub (Apr 11, 2022): Thanks for the PR!
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/sharpcompress#262