11using System ;
22using System . IO ;
3+ using System . Numerics ;
34using System . Text ;
5+ using ICSharpCode . SharpZipLib . Core ;
46
57namespace ICSharpCode . SharpZipLib . Tar
68{
@@ -594,13 +596,25 @@ public void ListContents()
594596 /// <param name="destinationDirectory">
595597 /// The destination directory into which to extract.
596598 /// </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 )
598610 {
599611 if ( isDisposed )
600612 {
601613 throw new ObjectDisposedException ( "TarArchive" ) ;
602614 }
603615
616+ var fullDistDir = Path . GetFullPath ( destinationDirectory ) ;
617+
604618 while ( true )
605619 {
606620 TarEntry entry = tarIn . GetNextEntry ( ) ;
@@ -613,7 +627,7 @@ public void ExtractContents(string destinationDirectory)
613627 if ( entry . TarHeader . TypeFlag == TarHeader . LF_LINK || entry . TarHeader . TypeFlag == TarHeader . LF_SYMLINK )
614628 continue ;
615629
616- ExtractEntry ( destinationDirectory , entry ) ;
630+ ExtractEntry ( fullDistDir , entry , allowParentTraversal ) ;
617631 }
618632 }
619633
@@ -627,7 +641,8 @@ public void ExtractContents(string destinationDirectory)
627641 /// <param name="entry">
628642 /// The TarEntry returned by tarIn.GetNextEntry().
629643 /// </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 )
631646 {
632647 OnProgressMessageEvent ( entry , null ) ;
633648
@@ -644,6 +659,11 @@ private void ExtractEntry(string destDir, TarEntry entry)
644659
645660 string destFile = Path . Combine ( destDir , name ) ;
646661
662+ if ( ! allowParentTraversal && ! Path . GetFullPath ( destFile ) . StartsWith ( destDir , StringComparison . InvariantCultureIgnoreCase ) )
663+ {
664+ throw new InvalidNameException ( "Parent traversal in paths is not allowed" ) ;
665+ }
666+
647667 if ( entry . IsDirectory )
648668 {
649669 EnsureDirectoryExists ( destFile ) ;
0 commit comments