in src/ICSharpCode.SharpZipLib/Tar/TarArchive.cs [645:710]
private void ExtractEntry(string destDir, TarEntry entry, bool allowParentTraversal)
{
OnProgressMessageEvent(entry, null);
string name = entry.Name;
if (Path.IsPathRooted(name))
{
// NOTE:
// for UNC names... \\machine\share\zoom\beet.txt gives \zoom\beet.txt
name = name.Substring(Path.GetPathRoot(name).Length);
}
name = name.Replace('/', Path.DirectorySeparatorChar);
string destFile = Path.Combine(destDir, name);
var destFileDir = Path.GetDirectoryName(Path.GetFullPath(destFile)) ?? "";
if (!allowParentTraversal && !destFileDir.StartsWith(destDir, StringComparison.InvariantCultureIgnoreCase))
{
throw new InvalidNameException("Parent traversal in paths is not allowed");
}
if (entry.IsDirectory)
{
EnsureDirectoryExists(destFile);
}
else
{
string parentDirectory = Path.GetDirectoryName(destFile);
EnsureDirectoryExists(parentDirectory);
bool process = true;
var fileInfo = new FileInfo(destFile);
if (fileInfo.Exists)
{
if (keepOldFiles)
{
OnProgressMessageEvent(entry, "Destination file already exists");
process = false;
}
else if ((fileInfo.Attributes & FileAttributes.ReadOnly) != 0)
{
OnProgressMessageEvent(entry, "Destination file already exists, and is read-only");
process = false;
}
}
if (process)
{
using (var outputStream = File.Create(destFile))
{
if (this.asciiTranslate)
{
// May need to translate the file.
ExtractAndTranslateEntry(destFile, outputStream);
}
else
{
// If translation is disabled, just copy the entry across directly.
tarIn.CopyEntryContents(outputStream);
}
}
}
}
}