Fix extract out of directory (dotnet/corefx#32127)
authorJeremy Kuhne <jeremy.kuhne@microsoft.com>
Fri, 7 Sep 2018 00:35:52 +0000 (17:35 -0700)
committerGitHub <noreply@github.com>
Fri, 7 Sep 2018 00:35:52 +0000 (17:35 -0700)
* Fix extract out of directory

Without ensuring a trailing directory separator you cannot compare paths for nesting.  `/Foo/Bar` does not contain `/Foo/Barber`, but does contain `/Foo/Bar/Bell`. This adds the separator and tests.

* Skip new test on NetFX

Commit migrated from https://github.com/dotnet/corefx/commit/a0fcd23ace1c8d692988cd0da4391cf7bf5e0ce6

src/libraries/System.IO.Compression.ZipFile/src/System/IO/Compression/ZipFileExtensions.ZipArchiveEntry.Extract.cs
src/libraries/System.IO.Compression.ZipFile/tests/ZipFile.Extract.cs

index 577d6d0..1e19a82 100644 (file)
@@ -98,6 +98,8 @@ namespace System.IO.Compression
             // Note that this will give us a good DirectoryInfo even if destinationDirectoryName exists:
             DirectoryInfo di = Directory.CreateDirectory(destinationDirectoryName);
             string destinationDirectoryFullPath = di.FullName;
+            if (!destinationDirectoryFullPath.EndsWith(Path.DirectorySeparatorChar))
+                destinationDirectoryFullPath += Path.DirectorySeparatorChar;
 
             string fileDestinationPath = Path.GetFullPath(Path.Combine(destinationDirectoryFullPath, source.FullName));
 
index b31303a..9850711 100644 (file)
@@ -46,6 +46,22 @@ namespace System.IO.Compression.Tests
             }
         }
 
+        [Theory]
+        [InlineData("../Foo")]
+        [InlineData("../Barbell")]
+        [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework, "Second case fails.")]
+        public void ExtractOutOfRoot(string entryName)
+        {
+            string archivePath = GetTestFilePath();
+            using (FileStream stream = new FileStream(archivePath, FileMode.Create))
+            using (ZipArchive archive = new ZipArchive(stream, ZipArchiveMode.Create, leaveOpen: true))
+            {
+                ZipArchiveEntry entry = archive.CreateEntry(entryName);
+            }
+
+            DirectoryInfo destination = Directory.CreateDirectory(Path.Combine(GetTestFilePath(), "Bar"));
+            Assert.Throws<IOException>(() => ZipFile.ExtractToDirectory(archivePath, destination.FullName));
+        }
 
         /// <summary>
         /// This test ensures that a zipfile with path names that are invalid to this OS will throw errors