1
1
using System ;
2
2
using System . IO ;
3
+ using System . Numerics ;
3
4
using System . Text ;
5
+ using ICSharpCode . SharpZipLib . Core ;
4
6
5
7
namespace ICSharpCode . SharpZipLib . Tar
6
8
{
@@ -594,13 +596,25 @@ public void ListContents()
594
596
/// <param name="destinationDirectory">
595
597
/// The destination directory into which to extract.
596
598
/// </param>
597
- public void ExtractContents ( string destinationDirectory )
599
+ public void ExtractContents ( string destinationDirectory )
600
+ => ExtractContents ( destinationDirectory , false ) ;
601
+
602
+ /// <summary>
603
+ /// Perform the "extract" command and extract the contents of the archive.
604
+ /// </summary>
605
+ /// <param name="destinationDirectory">
606
+ /// The destination directory into which to extract.
607
+ /// </param>
608
+ /// <param name="allowParentTraversal">Allow parent directory traversal in file paths (e.g. ../file)</param>
609
+ public void ExtractContents ( string destinationDirectory , bool allowParentTraversal )
598
610
{
599
611
if ( isDisposed )
600
612
{
601
613
throw new ObjectDisposedException ( "TarArchive" ) ;
602
614
}
603
615
616
+ var fullDistDir = Path . GetFullPath ( destinationDirectory ) ;
617
+
604
618
while ( true )
605
619
{
606
620
TarEntry entry = tarIn . GetNextEntry ( ) ;
@@ -613,7 +627,7 @@ public void ExtractContents(string destinationDirectory)
613
627
if ( entry . TarHeader . TypeFlag == TarHeader . LF_LINK || entry . TarHeader . TypeFlag == TarHeader . LF_SYMLINK )
614
628
continue ;
615
629
616
- ExtractEntry ( destinationDirectory , entry ) ;
630
+ ExtractEntry ( fullDistDir , entry , allowParentTraversal ) ;
617
631
}
618
632
}
619
633
@@ -627,7 +641,8 @@ public void ExtractContents(string destinationDirectory)
627
641
/// <param name="entry">
628
642
/// The TarEntry returned by tarIn.GetNextEntry().
629
643
/// </param>
630
- private void ExtractEntry ( string destDir , TarEntry entry )
644
+ /// <param name="allowParentTraversal">Allow parent directory traversal in file paths (e.g. ../file)</param>
645
+ private void ExtractEntry ( string destDir , TarEntry entry , bool allowParentTraversal )
631
646
{
632
647
OnProgressMessageEvent ( entry , null ) ;
633
648
@@ -644,6 +659,11 @@ private void ExtractEntry(string destDir, TarEntry entry)
644
659
645
660
string destFile = Path . Combine ( destDir , name ) ;
646
661
662
+ if ( ! allowParentTraversal && ! Path . GetFullPath ( destFile ) . StartsWith ( destDir , StringComparison . InvariantCultureIgnoreCase ) )
663
+ {
664
+ throw new InvalidNameException ( "Parent traversal in paths is not allowed" ) ;
665
+ }
666
+
647
667
if ( entry . IsDirectory )
648
668
{
649
669
EnsureDirectoryExists ( destFile ) ;
0 commit comments