From db5f4238d0261919b509428221a21c1964833a94 Mon Sep 17 00:00:00 2001
From: Adeel <3840695+am11@users.noreply.github.com>
Date: Tue, 18 Oct 2022 09:07:19 +0300
Subject: [PATCH 1/4] Trim file type bits from mode header
---
.../src/System/Formats/Tar/TarEntry.cs | 4 ++--
.../src/System/Formats/Tar/TarWriter.Unix.cs | 2 +-
.../TarFile.ExtractToDirectoryAsync.Stream.Tests.cs | 13 +++++++++++++
3 files changed, 16 insertions(+), 3 deletions(-)
diff --git a/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarEntry.cs b/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarEntry.cs
index a27df41f4c1c6a..09bb2b39433c49 100644
--- a/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarEntry.cs
+++ b/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarEntry.cs
@@ -138,10 +138,10 @@ public string LinkName
/// The value in this field has no effect on Windows platforms.
public UnixFileMode Mode
{
- get => (UnixFileMode)_header._mode;
+ get => (UnixFileMode)(_header._mode & 0xFFF); // mask to only keep least significant 12-bits
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
{
throw new ArgumentOutOfRangeException(nameof(value));
}
diff --git a/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarWriter.Unix.cs b/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarWriter.Unix.cs
index a691582178df6a..7a7f00f89806d6 100644
--- a/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarWriter.Unix.cs
+++ b/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarWriter.Unix.cs
@@ -66,7 +66,7 @@ private TarEntry ConstructEntryForWriting(string fullPath, string entryName, Fil
entry._header._aTime = TarHelpers.GetDateTimeOffsetFromSecondsSinceEpoch(status.ATime);
entry._header._cTime = TarHelpers.GetDateTimeOffsetFromSecondsSinceEpoch(status.CTime);
- entry._header._mode = status.Mode & 4095; // First 12 bits
+ entry._header._mode = status.Mode & 0xFFF; // least significant 12 bits
// Uid and UName
entry._header._uid = (int)status.Uid;
diff --git a/src/libraries/System.Formats.Tar/tests/TarFile/TarFile.ExtractToDirectoryAsync.Stream.Tests.cs b/src/libraries/System.Formats.Tar/tests/TarFile/TarFile.ExtractToDirectoryAsync.Stream.Tests.cs
index 70c6fcbf8049d4..82c37fb0dd0a70 100644
--- a/src/libraries/System.Formats.Tar/tests/TarFile/TarFile.ExtractToDirectoryAsync.Stream.Tests.cs
+++ b/src/libraries/System.Formats.Tar/tests/TarFile/TarFile.ExtractToDirectoryAsync.Stream.Tests.cs
@@ -97,6 +97,19 @@ public async Task ExtractEntry_ManySubfolderSegments_NoPrecedingDirectoryEntries
}
}
+ [Fact]
+ public async Task ExtractEntry_DockerImageTarWithFileTypeInDirectoriesInMode_SuccessfullyExtracts_Async()
+ {
+ using (TempDirectory root = new TempDirectory())
+ {
+ await using MemoryStream archiveStream = GetTarMemoryStream(CompressionMethod.Uncompressed, "golang_tar", "docker-hello-world");
+ await TarFile.ExtractToDirectoryAsync(archiveStream, root.Path, overwriteFiles: true);
+
+ Assert.True(File.Exists(Path.Join(root.Path, "manifest.json")));
+ Assert.True(File.Exists(Path.Join(root.Path, "repositories")));
+ }
+ }
+
[Theory]
[InlineData(TarEntryType.SymbolicLink)]
[InlineData(TarEntryType.HardLink)]
From 04bf3d07173550388f45f5cde7b43af52c4a8299 Mon Sep 17 00:00:00 2001
From: Adeel <3840695+am11@users.noreply.github.com>
Date: Tue, 18 Oct 2022 09:40:37 +0300
Subject: [PATCH 2/4] Define and use ValidUnixFileModes
---
.../src/System/Formats/Tar/TarEntry.cs | 6 ++++--
.../src/System/Formats/Tar/TarHelpers.Unix.cs | 14 ++++++++++++++
.../src/System/Formats/Tar/TarWriter.Unix.cs | 3 ++-
3 files changed, 20 insertions(+), 3 deletions(-)
diff --git a/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarEntry.cs b/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarEntry.cs
index 09bb2b39433c49..5c08ec75f74da5 100644
--- a/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarEntry.cs
+++ b/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarEntry.cs
@@ -138,10 +138,12 @@ public string LinkName
/// The value in this field has no effect on Windows platforms.
public UnixFileMode Mode
{
- get => (UnixFileMode)(_header._mode & 0xFFF); // mask to only keep least significant 12-bits
+ // Some paths do not use the setter, and we want to return valid UnixFileMode.
+ // This mask only keeps the least significant 12 bits.
+ get => (UnixFileMode)(_header._mode & (int)TarHelpers.ValidUnixFileModes);
set
{
- if ((int)value is < 0 or > 0xFFF) // 0xFFF (4095) in decimal is 7777 in octal
+ if ((value & ~TarHelpers.ValidUnixFileModes) != 0) // throw on invalid UnixFileModes
{
throw new ArgumentOutOfRangeException(nameof(value));
}
diff --git a/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarHelpers.Unix.cs b/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarHelpers.Unix.cs
index 3e0a0b814484d4..b1e2656c3fd951 100644
--- a/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarHelpers.Unix.cs
+++ b/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarHelpers.Unix.cs
@@ -11,6 +11,20 @@ internal static partial class TarHelpers
{
private static readonly Lazy s_umask = new Lazy(DetermineUMask);
+ internal const UnixFileMode ValidUnixFileModes =
+ UnixFileMode.UserRead |
+ UnixFileMode.UserWrite |
+ UnixFileMode.UserExecute |
+ UnixFileMode.GroupRead |
+ UnixFileMode.GroupWrite |
+ UnixFileMode.GroupExecute |
+ UnixFileMode.OtherRead |
+ UnixFileMode.OtherWrite |
+ UnixFileMode.OtherExecute |
+ UnixFileMode.StickyBit |
+ UnixFileMode.SetGroup |
+ UnixFileMode.SetUser;
+
private static UnixFileMode DetermineUMask()
{
// To determine the umask, we'll create a file with full permissions and see
diff --git a/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarWriter.Unix.cs b/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarWriter.Unix.cs
index 7a7f00f89806d6..357e4a8a7587f1 100644
--- a/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarWriter.Unix.cs
+++ b/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarWriter.Unix.cs
@@ -66,7 +66,8 @@ private TarEntry ConstructEntryForWriting(string fullPath, string entryName, Fil
entry._header._aTime = TarHelpers.GetDateTimeOffsetFromSecondsSinceEpoch(status.ATime);
entry._header._cTime = TarHelpers.GetDateTimeOffsetFromSecondsSinceEpoch(status.CTime);
- entry._header._mode = status.Mode & 0xFFF; // least significant 12 bits
+ // This mask only keeps the least significant 12 bits valid for UnixFileModes
+ entry._header._mode = status.Mode & (int)TarHelpers.ValidUnixFileModes;
// Uid and UName
entry._header._uid = (int)status.Uid;
From cec85bfaa072e84312393542324880c6753003a1 Mon Sep 17 00:00:00 2001
From: Adeel <3840695+am11@users.noreply.github.com>
Date: Tue, 18 Oct 2022 13:03:38 +0300
Subject: [PATCH 3/4] Rev System.Formats.Tar.TestData version
---
eng/Version.Details.xml | 4 ++--
eng/Versions.props | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml
index cecaf60d795143..cf798fd808027c 100644
--- a/eng/Version.Details.xml
+++ b/eng/Version.Details.xml
@@ -162,9 +162,9 @@
https://github.com/dotnet/runtime-assets
98dccc055b925524dfb77fb9d1b54598475825ac
-
+
https://github.com/dotnet/runtime-assets
- 98dccc055b925524dfb77fb9d1b54598475825ac
+ 6d1bdc7e14a076deb791bf469202bc719a264abd
https://github.com/dotnet/runtime-assets
diff --git a/eng/Versions.props b/eng/Versions.props
index bb65849384cf67..50af6016cbe346 100644
--- a/eng/Versions.props
+++ b/eng/Versions.props
@@ -141,7 +141,7 @@
7.0.0-beta.22510.1
7.0.0-beta.22510.1
7.0.0-beta.22510.1
- 7.0.0-beta.22510.1
+ 7.0.0-beta.22518.1
7.0.0-beta.22510.1
7.0.0-beta.22510.1
7.0.0-beta.22510.1
From 6af0213e235f05e9c8748f245384864eaf7f004a Mon Sep 17 00:00:00 2001
From: Adeel <3840695+am11@users.noreply.github.com>
Date: Tue, 18 Oct 2022 13:46:10 +0300
Subject: [PATCH 4/4] Move ValidUnixFileModes to shared helpers
---
.../src/System/Formats/Tar/TarHelpers.Unix.cs | 14 --------------
.../src/System/Formats/Tar/TarHelpers.cs | 14 ++++++++++++++
2 files changed, 14 insertions(+), 14 deletions(-)
diff --git a/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarHelpers.Unix.cs b/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarHelpers.Unix.cs
index b1e2656c3fd951..3e0a0b814484d4 100644
--- a/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarHelpers.Unix.cs
+++ b/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarHelpers.Unix.cs
@@ -11,20 +11,6 @@ internal static partial class TarHelpers
{
private static readonly Lazy s_umask = new Lazy(DetermineUMask);
- internal const UnixFileMode ValidUnixFileModes =
- UnixFileMode.UserRead |
- UnixFileMode.UserWrite |
- UnixFileMode.UserExecute |
- UnixFileMode.GroupRead |
- UnixFileMode.GroupWrite |
- UnixFileMode.GroupExecute |
- UnixFileMode.OtherRead |
- UnixFileMode.OtherWrite |
- UnixFileMode.OtherExecute |
- UnixFileMode.StickyBit |
- UnixFileMode.SetGroup |
- UnixFileMode.SetUser;
-
private static UnixFileMode DetermineUMask()
{
// To determine the umask, we'll create a file with full permissions and see
diff --git a/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarHelpers.cs b/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarHelpers.cs
index d5393b45ffc834..45cae1c2759044 100644
--- a/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarHelpers.cs
+++ b/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarHelpers.cs
@@ -21,6 +21,20 @@ internal static partial class TarHelpers
internal const int MaxBufferLength = 4096;
internal const long MaxSizeLength = (1L << 33) - 1; // Max value of 11 octal digits = 2^33 - 1 or 8 Gb.
+ internal const UnixFileMode ValidUnixFileModes =
+ UnixFileMode.UserRead |
+ UnixFileMode.UserWrite |
+ UnixFileMode.UserExecute |
+ UnixFileMode.GroupRead |
+ UnixFileMode.GroupWrite |
+ UnixFileMode.GroupExecute |
+ UnixFileMode.OtherRead |
+ UnixFileMode.OtherWrite |
+ UnixFileMode.OtherExecute |
+ UnixFileMode.StickyBit |
+ UnixFileMode.SetGroup |
+ UnixFileMode.SetUser;
+
// Default mode for TarEntry created for a file-type.
private const UnixFileMode DefaultFileMode =
UnixFileMode.UserRead | UnixFileMode.UserWrite |