mirror of
https://github.com/adamhathcock/sharpcompress.git
synced 2026-09-22 23:15:20 +00:00
Tar symlink extraction
Extended SharpCompress.Common.ExtractionOptions with a delegate to write symbolic links. If not is null, and a symbolic link is encountered, an exception is thrown. Removed Mono.Posix.NETStandard from the library, but added to the .NET Core 2.1 test application. Extended the test to implement the delegate.
This commit is contained in:
@@ -68,18 +68,15 @@ namespace SharpCompress.Common
|
||||
ExtractionOptions options,
|
||||
Action<string, FileMode> openAndWrite)
|
||||
{
|
||||
#if NETSTANDARD2_0
|
||||
if (entry.LinkTarget != null)
|
||||
{
|
||||
var link = new Mono.Unix.UnixSymbolicLinkInfo(destinationFileName);
|
||||
if (System.IO.File.Exists(destinationFileName))
|
||||
if (null == options.WriteSymbolicLink)
|
||||
{
|
||||
link.Delete(); // equivalent to ln -s -f
|
||||
throw new ExtractionException("Entry is a symbolic link but ExtractionOptions.WriteSymbolicLink delegate is null");
|
||||
}
|
||||
link.CreateSymbolicLinkTo(entry.LinkTarget);
|
||||
options.WriteSymbolicLink(destinationFileName, entry.LinkTarget);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
FileMode fm = FileMode.Create;
|
||||
options = options ?? new ExtractionOptions()
|
||||
|
||||
@@ -21,5 +21,14 @@
|
||||
/// preserve windows file attributes
|
||||
/// </summary>
|
||||
public bool PreserveAttributes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Delegate for writing symbolic links to disk.
|
||||
/// sourcePath is where the symlink is created.
|
||||
/// targetPath is what the symlink refers to.
|
||||
/// </summary>
|
||||
public delegate void SymbolicLinkWriterDelegate(string sourcePath, string targetPath);
|
||||
|
||||
public SymbolicLinkWriterDelegate WriteSymbolicLink;
|
||||
}
|
||||
}
|
||||
@@ -34,7 +34,6 @@
|
||||
<DefineConstants>$(DefineConstants);NETCORE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' ">
|
||||
<PackageReference Include="Mono.Posix.NETStandard" Version="1.0.0" />
|
||||
<PackageReference Include="System.Text.Encoding.CodePages" Version="4.5.0" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -16,5 +16,6 @@
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.0" />
|
||||
<PackageReference Include="xunit" Version="2.4.0" />
|
||||
<PackageReference Include="Xunit.SkippableFact" Version="1.3.6" />
|
||||
<PackageReference Include="Mono.Posix.NETStandard" Version="1.0.0" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -190,6 +190,8 @@ namespace SharpCompress.Test.Tar
|
||||
[Fact]
|
||||
public void Tar_GZip_With_Symlink_Entries()
|
||||
{
|
||||
var isWindows = System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(
|
||||
System.Runtime.InteropServices.OSPlatform.Windows);
|
||||
using (Stream stream = File.OpenRead(Path.Combine(TEST_ARCHIVES_PATH, "TarWithSymlink.tar.gz")))
|
||||
using (var reader = TarReader.Open(stream))
|
||||
{
|
||||
@@ -204,21 +206,42 @@ namespace SharpCompress.Test.Tar
|
||||
new ExtractionOptions()
|
||||
{
|
||||
ExtractFullPath = true,
|
||||
Overwrite = true
|
||||
Overwrite = true,
|
||||
WriteSymbolicLink = (sourcePath, targetPath) =>
|
||||
{
|
||||
if (!isWindows)
|
||||
{
|
||||
var link = new Mono.Unix.UnixSymbolicLinkInfo(sourcePath);
|
||||
if (System.IO.File.Exists(sourcePath))
|
||||
{
|
||||
link.Delete(); // equivalent to ln -s -f
|
||||
}
|
||||
link.CreateSymbolicLinkTo(targetPath);
|
||||
}
|
||||
}
|
||||
});
|
||||
if (reader.Entry.LinkTarget != null)
|
||||
if (!isWindows)
|
||||
{
|
||||
#if NETSTANDARD2_0
|
||||
var link = new Mono.Unix.UnixSymbolicLinkInfo(reader.Entry.Key);
|
||||
if (link.HasContents)
|
||||
if (reader.Entry.LinkTarget != null)
|
||||
{
|
||||
Assert.Equal(link.GetContents(), reader.Entry.LinkTarget);
|
||||
var path = System.IO.Path.Combine(SCRATCH_FILES_PATH, reader.Entry.Key);
|
||||
var link = new Mono.Unix.UnixSymbolicLinkInfo(path);
|
||||
if (link.HasContents)
|
||||
{
|
||||
// need to convert the link to an absolute path for comparison
|
||||
var target = reader.Entry.LinkTarget;
|
||||
var realTarget = System.IO.Path.GetFullPath(
|
||||
System.IO.Path.Combine($"{System.IO.Path.GetDirectoryName(path)}",
|
||||
target)
|
||||
);
|
||||
|
||||
Assert.Equal(realTarget, link.GetContents().ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.True(false, "Symlink has no target");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.True(false);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user