Skip to content
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

Tar: Ensure trailing separator in sanitized path for extraction #87534

Merged
merged 1 commit into from
Jun 20, 2023

Conversation

carlossanlop
Copy link
Member

No description provided.

@ghost
Copy link

ghost commented Jun 13, 2023

Tagging subscribers to this area: @dotnet/area-system-formats-tar
See info in area-owners.md if you want to be subscribed.

Issue Details

null

Author: carlossanlop
Assignees: carlossanlop
Labels:

area-System.Formats.Tar

Milestone: -

var longFolderNames = new string[]
{
// Long path with many short segment names and a filename
"folderfolder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you generate these rather than paste in big strings? It's self documenting. Tests do this various ways eg string.Create, Enumerable.Repeat, maybe there's some Utility class. The micro benchmarks have another way, etc

[InlineData(TarEntryFormat.Gnu)]
public async Task ExtractToDirectory_ExactRootDirMatch_HardLinks_Throws_Async(TarEntryFormat format)
{
await ExtractToDirectory_ExactRootDirMatch_Links_Throws_Async(format, TarEntryType.HardLink, inverted: false);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be cleaner to have one method call with a foreach over new bool[] { true, false }

string linkPath = Path.Join(entryFolderPath, linkFileName);
string linkTargetPath = Path.Join(destinationFolderPath, linkTargetFileName);

Directory.CreateDirectory(entryFolderPath);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it worth extracting CreateDirectories(string[]) and using across your tests?

string entryFolderName = "folder";
string destinationFolderName = "folderSibling";

using TempDirectory root = new TempDirectory();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Possibly creating temp directory is cleaner in a single GlobalSetup?

Just looking for ways to make these tests shorter and cleaner by removing repeated stuff

fileName = PathInternal.DirectorySeparatorCharAsString;
}

string sanitizedPath = Path.Join(Path.GetDirectoryName(normalizedPath), ArchivingUtils.SanitizeEntryFilePath(fileName));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
string sanitizedPath = Path.Join(Path.GetDirectoryName(normalizedPath), ArchivingUtils.SanitizeEntryFilePath(fileName));
string sanitizedPath = Path.Join(Path.GetDirectoryName(normalizedPath), ArchivingUtils.SanitizeEntryFilePath(fileName));

Fwiw I think "GetSanitizedEntryFilePath" reads better than SanitizeEntryFilePath as it's idempotent.
(Or SanitizePath?)

@@ -365,9 +365,17 @@ internal Task ExtractRelativeToDirectoryAsync(string destinationDirectoryPath, b
// If the path can be extracted in the specified destination directory, returns the full path with sanitized file name. Otherwise, returns null.
private static string? GetSanitizedFullPath(string destinationDirectoryFullPath, string path)
{
destinationDirectoryFullPath = PathInternal.EnsureTrailingSeparator(destinationDirectoryFullPath);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just before this method gets called, there's a call that removes the directory separator:

destinationDirectoryPath = Path.TrimEndingDirectorySeparator(destinationDirectoryPath);

Probably that can be removed?

Can we also add a call to PathInternal.EnsureTrailingSeparator higher up the call stack when called from TarFile.ExtractToDirectory to avoid allocating a string here each time an entry gets extracted?

fileName = PathInternal.DirectorySeparatorCharAsString;
}

string sanitizedPath = Path.Join(Path.GetDirectoryName(normalizedPath), ArchivingUtils.SanitizeEntryFilePath(fileName));
Copy link
Member

@tmds tmds Jun 14, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're only calling ArchivingUtils.SanitizeEntryFilePath on the fileName, probably it makes sense to call it on path (which is the path that was stored in the entry) at the start of this method?

I think we no longer need to get the fileName then, which will simplify this method.

Copy link
Member

@GrabYourPitchforks GrabYourPitchforks left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As a port of 806235b, LGTM.

@carlossanlop
Copy link
Member Author

@danmoseley @tmds If you have no objections, I'd like to get this merged now to make sure it goes into the Preview6 snap. I opened issue #87835 as a reminder.

@carlossanlop carlossanlop merged commit ffb3524 into dotnet:main Jun 20, 2023
@carlossanlop carlossanlop deleted the TarEnsureSeparator branch June 20, 2023 20:10
@ghost ghost locked as resolved and limited conversation to collaborators Jul 21, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants