11using System ;
22using System . IO ;
3+ using System . Numerics ;
34using System . Text ;
5+ using ICSharpCode . SharpZipLib . Core ;
46
57namespace ICSharpCode . SharpZipLib . Tar
68{
@@ -594,7 +596,17 @@ 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 {
@@ -613,7 +625,7 @@ public void ExtractContents(string destinationDirectory)
613625 if ( entry . TarHeader . TypeFlag == TarHeader . LF_LINK || entry . TarHeader . TypeFlag == TarHeader . LF_SYMLINK )
614626 continue ;
615627
616- ExtractEntry ( destinationDirectory , entry ) ;
628+ ExtractEntry ( destinationDirectory , entry , allowParentTraversal ) ;
617629 }
618630 }
619631
@@ -627,7 +639,8 @@ public void ExtractContents(string destinationDirectory)
627639 /// <param name="entry">
628640 /// The TarEntry returned by tarIn.GetNextEntry().
629641 /// </param>
630- private void ExtractEntry ( string destDir , TarEntry entry )
642+ /// <param name="allowParentTraversal">Allow parent directory traversal in file paths (e.g. ../file)</param>
643+ private void ExtractEntry ( string destDir , TarEntry entry , bool allowParentTraversal )
631644 {
632645 OnProgressMessageEvent ( entry , null ) ;
633646
@@ -644,6 +657,11 @@ private void ExtractEntry(string destDir, TarEntry entry)
644657
645658 string destFile = Path . Combine ( destDir , name ) ;
646659
660+ if ( ! allowParentTraversal && ! Path . GetFullPath ( destFile ) . StartsWith ( destDir , StringComparison . InvariantCultureIgnoreCase ) )
661+ {
662+ throw new InvalidNameException ( "Parent traversal in paths is not allowed" ) ;
663+ }
664+
647665 if ( entry . IsDirectory )
648666 {
649667 EnsureDirectoryExists ( destFile ) ;
0 commit comments