-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Allow spaces in octal attributes #74358
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
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||
|---|---|---|---|---|
| @@ -1,4 +1,4 @@ | ||||
| // Licensed to the .NET Foundation under one or more agreements. | ||||
| // Licensed to the .NET Foundation under one or more agreements. | ||||
| // The .NET Foundation licenses this file to you under the MIT license. | ||||
|
|
||||
| using System.Collections.Generic; | ||||
|
|
@@ -125,28 +125,33 @@ public void Read_Archive_LongFileName_Over100_Under255(TarEntryFormat format, Te | |||
| public void Read_Archive_LongPath_Over255(TarEntryFormat format, TestTarFormat testFormat) => | ||||
| Read_Archive_LongPath_Over255_Internal(format, testFormat); | ||||
|
|
||||
| [Fact] | ||||
| public void Read_NodeTarArchives_Successfully() | ||||
| [Theory] | ||||
| [InlineData("node-tar")] | ||||
| [InlineData("tar-rs")] | ||||
| public void Read_TestArchives_Successfully(string subset) | ||||
|
||||
| { | ||||
| string nodeTarPath = Path.Join(Directory.GetCurrentDirectory(), "tar", "node-tar"); | ||||
| string nodeTarPath = Path.Join(Directory.GetCurrentDirectory(), "tar", subset); | ||||
| foreach (string file in Directory.EnumerateFiles(nodeTarPath, "*.tar", SearchOption.AllDirectories)) | ||||
| { | ||||
| using FileStream sourceStream = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read); | ||||
| using var reader = new TarReader(sourceStream); | ||||
|
|
||||
| TarEntry? entry = null; | ||||
| while (true) | ||||
| while ((entry = reader.GetNextEntry()) != null) | ||||
| { | ||||
| Exception ex = Record.Exception(() => entry = reader.GetNextEntry()); | ||||
| Assert.Null(ex); | ||||
|
|
||||
| if (entry is null) break; | ||||
|
|
||||
| ex = Record.Exception(() => entry.Name); | ||||
| Assert.Null(ex); | ||||
|
|
||||
| ex = Record.Exception(() => entry.Length); | ||||
| Assert.Null(ex); | ||||
| Assert.NotNull(entry.Name); | ||||
| Assert.True(Enum.IsDefined(entry.EntryType)); | ||||
|
||||
| typeFlag: (TarEntryType)buffer[FieldLocations.TypeFlag]) |
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.
Those files have known entry types, so this assert is valid for the current set of assets. If in the future, we ever updated assets in those directories from upstream into dotnet/runtime-assets, and those new files have some unknown entry types (very unlikely), we can adjust the code accordingly.
Outdated
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 directory entry check is unnecessary if the entry.DataStream is already being checked for null a few lines below.
Outdated
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.
Nothing is being done with the memory stream. What is this for?
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.
I didn't look into the implementation of the stream that Tar returns; I read it into a dummy stream to ensure it could successfully read to the end. It seems a reasonable small check.
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.
Ah alright, that's fine. Although we already have tests that verify both seekable and unseekable data streams can be read.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -20,19 +20,6 @@ public void MalformedArchive_TooSmall() | |
| Assert.Throws<EndOfStreamException>(() => reader.GetNextEntry()); | ||
| } | ||
|
|
||
| [Fact] | ||
| public void MalformedArchive_HeaderSize() | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why were these tests removed?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Right, but I am concerned that we now allow a whole header to contain invalid data. I do not think we want this level of flexiblity. The test that is being removed would've thrown at some point due to having 512 consecutive 0x1 bytes. Let's analyze each one of the fields in the header: From V7:
From Ustar and Gnu:
Then since the size had some data, but we didn't find any characters, we would set size as 0 with your change. So no data. |
||
| { | ||
| using MemoryStream malformed = new MemoryStream(); | ||
| byte[] buffer = new byte[512]; // Minimum length of any header | ||
| Array.Fill<byte>(buffer, 0x1); | ||
| malformed.Write(buffer); | ||
| malformed.Seek(0, SeekOrigin.Begin); | ||
|
|
||
| using TarReader reader = new TarReader(malformed); | ||
| Assert.Throws<FormatException>(() => reader.GetNextEntry()); | ||
| } | ||
|
|
||
| [Fact] | ||
| public void EmptyArchive() | ||
| { | ||
|
|
||
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.
Which assets have octal fields with non-octal characters on either end? I'm concerned that we are basically allowing garbage and not respecting the tar spec anymore.
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.
Yea let's not anywhere intentionally be more lenient than we discover existing tools are.
Uh oh!
There was an error while loading. Please reload this page.
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.
@danmoseley, it is exactly as lenient as libarchive's octal parsing, it allows any non-octal character at the beginning and end.
GNU tar and busybox implementations allow both leading and trailing whitespaces and nulls.
.NET's implementation is the strictest one, we are only ignoring null and spaces when they appear at the end, and we do not allow them at the beginning.
I haven't find formal specification calling out for and against these behaviors, so it is up to us to decide which existing implementation to follow.
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.
But ignoring nulls and spaces is not the same as ignoring any character that is either smaller than '0' or larger than '7'.
Uh oh!
There was an error while loading. Please reload this page.
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.
libarchive ignores any non-octal character. :)
https://github.com/libarchive/libarchive/blob/9e5279615033fa073d0bbae83b366359eab3b62f/contrib/untar.c#L45
if this is too lenient, I can confine it to only allow nulls and spaces.