diff --git a/src/SharpCompress/Common/Zip/Headers/DirectoryEntryHeader.cs b/src/SharpCompress/Common/Zip/Headers/DirectoryEntryHeader.cs index 6ca248e4..8cf4f4ad 100644 --- a/src/SharpCompress/Common/Zip/Headers/DirectoryEntryHeader.cs +++ b/src/SharpCompress/Common/Zip/Headers/DirectoryEntryHeader.cs @@ -123,8 +123,6 @@ internal class DirectoryEntryHeader : ZipFileEntry public long RelativeOffsetOfEntryHeader { get; set; } - public uint ExternalFileAttributes { get; set; } - public ushort InternalFileAttributes { get; set; } public ushort DiskNumberStart { get; set; } diff --git a/src/SharpCompress/Common/Zip/Headers/ZipFileEntry.cs b/src/SharpCompress/Common/Zip/Headers/ZipFileEntry.cs index 6842cba6..bd36b065 100644 --- a/src/SharpCompress/Common/Zip/Headers/ZipFileEntry.cs +++ b/src/SharpCompress/Common/Zip/Headers/ZipFileEntry.cs @@ -121,5 +121,7 @@ internal abstract class ZipFileEntry : ZipHeader internal bool IsZip64 => CompressedSize >= uint.MaxValue; + internal uint ExternalFileAttributes { get; set; } + internal string? Comment { get; set; } } diff --git a/src/SharpCompress/Common/Zip/SeekableZipHeaderFactory.cs b/src/SharpCompress/Common/Zip/SeekableZipHeaderFactory.cs index e610c080..005f6480 100644 --- a/src/SharpCompress/Common/Zip/SeekableZipHeaderFactory.cs +++ b/src/SharpCompress/Common/Zip/SeekableZipHeaderFactory.cs @@ -152,6 +152,7 @@ internal sealed class SeekableZipHeaderFactory : ZipHeaderFactory // populate fields only known from the DirectoryEntryHeader localEntryHeader.HasData = directoryEntryHeader.HasData; + localEntryHeader.ExternalFileAttributes = directoryEntryHeader.ExternalFileAttributes; localEntryHeader.Comment = directoryEntryHeader.Comment; if (FlagUtility.HasFlag(localEntryHeader.Flags, HeaderFlags.UsePostDataDescriptor)) diff --git a/src/SharpCompress/Common/Zip/ZipEntry.cs b/src/SharpCompress/Common/Zip/ZipEntry.cs index c0b677d7..10cc1ba2 100644 --- a/src/SharpCompress/Common/Zip/ZipEntry.cs +++ b/src/SharpCompress/Common/Zip/ZipEntry.cs @@ -84,5 +84,7 @@ public class ZipEntry : Entry internal override IEnumerable Parts => _filePart.Empty(); + public override int? Attrib => (int?)_filePart?.Header.ExternalFileAttributes; + public string? Comment => _filePart?.Header.Comment; } diff --git a/tests/SharpCompress.Test/Zip/ZipArchiveTests.cs b/tests/SharpCompress.Test/Zip/ZipArchiveTests.cs index 8b886afe..58ebfa1c 100644 --- a/tests/SharpCompress.Test/Zip/ZipArchiveTests.cs +++ b/tests/SharpCompress.Test/Zip/ZipArchiveTests.cs @@ -832,4 +832,15 @@ public class ZipArchiveTests : ArchiveTests using var _ = firstEntry.OpenEntryStream(); Assert.Equal(29, firstEntry.Comment.Length); } + + [Fact] + public void Zip_FilePermissions() + { + using var archive = ArchiveFactory.Open(Path.Combine(TEST_ARCHIVES_PATH, "Zip.644.zip")); + + var firstEntry = archive.Entries.First(); + const int S_IFREG = 0x8000; + const int expected = (S_IFREG | 0b110_100_100) << 16; // 0644 mode regular file + Assert.Equal(expected, firstEntry.Attrib); + } } diff --git a/tests/TestArchives/Archives/Zip.644.zip b/tests/TestArchives/Archives/Zip.644.zip new file mode 100644 index 00000000..71a786be Binary files /dev/null and b/tests/TestArchives/Archives/Zip.644.zip differ