龙腾猫跃 5 месяцев назад
Родитель
Сommit
19ceef907c
2 измененных файлов с 108 добавлено и 112 удалено
  1. 18 2
      Tests/TestUtils.cs
  2. 90 110
      Tests/Utils/FileUtilsTest.cs

+ 18 - 2
Tests/TestUtils.cs

@@ -2,10 +2,26 @@
 public static class TestUtils {
 
     /// <summary>
-    /// 获取测试用文件的路径。
+    /// 获取一个在极端路径下的测试文件夹。
+    /// </summary>
+    public static string GetTempFolder(string? identifier = null) {
+        string folderPath = Path.Combine(
+            Path.GetTempPath(), "PCL", "Tests", 
+            (identifier ?? "Test") + "-" + Guid.NewGuid().ToString(), 
+            "文件夹 Dir_!@#$%^&()_+={}[];',_",
+            new string('X', 200), new string('X', 200));
+        Directory.CreateDirectory(@"\\?\" + folderPath);
+        return folderPath;
+    }
+
+    /// <summary>
+    /// 将指定的测试用文件输出到一个极端路径下,然后返回文件路径。
     /// </summary>
     public static string GetTestFile(string directoryName, string fileName) {
-        return Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "TestFiles", directoryName, fileName);
+        var sourceFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "TestFiles", directoryName, fileName);
+        var distPath = Path.Combine(GetTempFolder("GetTestFile"), Path.GetFileName(sourceFilePath));
+        File.Copy(sourceFilePath, @"\\?\" + distPath);
+        return distPath;
     }
 
 }

+ 90 - 110
Tests/Utils/FileUtilsTest.cs

@@ -23,6 +23,96 @@ public class FileUtilsTest : IDisposable {
         Assert.Throws<InvalidDataException>(() => FileUtils.OpenZip(TestUtils.GetTestFile(nameof(FileUtils), "Not zip.zip")));
     }
 
+    [Fact(DisplayName = nameof(ExtractToDirectory))]
+    public void ExtractToDirectory() {
+
+
+
+
+
+        //const string fileContent = "hello extract";
+        //string zipPath = CreateZipWithEncoding("single.zip", new UTF8Encoding(false, true),
+        //    ("file.txt", fileContent));
+        //string outDir = Path.Combine(_tempDir, "out_single");
+        //
+        //FileUtils.ExtractToDirectory(zipPath, outDir);
+        //
+        //string extractedFile = Path.Combine(outDir, "file.txt");
+        //Assert.True(File.Exists(extractedFile));
+        //Assert.Equal(fileContent, ReadFile(extractedFile));
+        //
+        //string zipPath = CreateZipWithEncoding("multi_extract.zip", new UTF8Encoding(false, true),
+        //    ("a.txt", "aaa"),
+        //    ("b.txt", "bbb"));
+        //string outDir = Path.Combine(_tempDir, "out_multi");
+        //
+        //FileUtils.ExtractToDirectory(zipPath, outDir);
+        //
+        //Assert.True(File.Exists(Path.Combine(outDir, "a.txt")));
+        //Assert.True(File.Exists(Path.Combine(outDir, "b.txt")));
+        //
+        //string zipPath = CreateZipWithEncoding("subdir.zip", new UTF8Encoding(false, true),
+        //    ("subdir/nested.txt", "nested content"));
+        //string outDir = Path.Combine(_tempDir, "out_subdir");
+        //
+        //FileUtils.ExtractToDirectory(zipPath, outDir);
+        //
+        //string nestedFile = Path.Combine(outDir, "subdir", "nested.txt");
+        //Assert.True(File.Exists(nestedFile));
+        //Assert.Equal("nested content", ReadFile(nestedFile));
+        //
+        //string zipPath = CreateZipWithEncoding("autocreate.zip", new UTF8Encoding(false, true),
+        //    ("f.txt", "x"));
+        //string outDir = Path.Combine(_tempDir, "nonexistent", "deep", "dir");
+        //
+        //FileUtils.ExtractToDirectory(zipPath, outDir);
+        //
+        //Assert.True(Directory.Exists(outDir));
+        //
+        //string zipPath = CreateZipWithEncoding("overwrite.zip", new UTF8Encoding(false, true),
+        //    ("f.txt", "new content"));
+        //string outDir = Path.Combine(_tempDir, "out_overwrite");
+        //Directory.CreateDirectory(outDir);
+        //File.WriteAllText(Path.Combine(outDir, "f.txt"), "old content");
+        //
+        //FileUtils.ExtractToDirectory(zipPath, outDir);
+        //
+        //Assert.Equal("new content", ReadFile(Path.Combine(outDir, "f.txt")));
+        //
+        //// 手动构造一个包含路径穿越条目(../../evil.txt)的 zip
+        //string zipPath = Path.Combine(_tempDir, "zipslip.zip");
+        //using (var stream = File.Create(zipPath))
+        //using (var archive = new ZipArchive(stream, ZipArchiveMode.Create, leaveOpen: false, new UTF8Encoding(false, true))) {
+        //    var entry = archive.CreateEntry("../../evil.txt");
+        //    using var writer = new StreamWriter(entry.Open());
+        //    writer.Write("pwned");
+        //}
+        //string outDir = Path.Combine(_tempDir, "out_zipslip");
+        //Directory.CreateDirectory(outDir);
+        //
+        //Assert.Throws<UnauthorizedAccessException>(() => FileUtils.ExtractToDirectory(zipPath, outDir));
+        //
+        //const string innerContent = "gzip content";
+        //const string innerFileName = "inner.txt";
+        //string gzPath = CreateGzFile(innerFileName, innerContent);
+        //string outDir = Path.Combine(_tempDir, "out_gz");
+        //
+        //FileUtils.ExtractToDirectory(gzPath, outDir);
+        //
+        //string extractedFile = Path.Combine(outDir, innerFileName);
+        //Assert.True(File.Exists(extractedFile));
+        //Assert.Equal(innerContent, ReadFile(extractedFile));
+        //
+        //// jar 文件实际上是 zip 格式
+        //string zipPath = CreateZipWithEncoding("app.jar", new UTF8Encoding(false, true),
+        //    ("META-INF/MANIFEST.MF", "Manifest-Version: 1.0\r\n"));
+        //string outDir = Path.Combine(_tempDir, "out_jar");
+        //
+        //FileUtils.ExtractToDirectory(zipPath, outDir);
+        //
+        //Assert.True(File.Exists(Path.Combine(outDir, "META-INF", "MANIFEST.MF")));
+    }
+
     #endregion
 
 
@@ -92,116 +182,6 @@ public class FileUtilsTest : IDisposable {
 
     #endregion
 
-    #region ExtractToDirectory 测试
-
-    
-    public void ExtractToDirectory_ZipWithSingleFile_ExtractsCorrectly() {
-        const string fileContent = "hello extract";
-        string zipPath = CreateZipWithEncoding("single.zip", new UTF8Encoding(false, true),
-            ("file.txt", fileContent));
-        string outDir = Path.Combine(_tempDir, "out_single");
-
-        FileUtils.ExtractToDirectory(zipPath, outDir);
-
-        string extractedFile = Path.Combine(outDir, "file.txt");
-        Assert.True(File.Exists(extractedFile));
-        Assert.Equal(fileContent, ReadFile(extractedFile));
-    }
-
-    
-    public void ExtractToDirectory_ZipWithMultipleFiles_AllExtracted() {
-        string zipPath = CreateZipWithEncoding("multi_extract.zip", new UTF8Encoding(false, true),
-            ("a.txt", "aaa"),
-            ("b.txt", "bbb"));
-        string outDir = Path.Combine(_tempDir, "out_multi");
-
-        FileUtils.ExtractToDirectory(zipPath, outDir);
-
-        Assert.True(File.Exists(Path.Combine(outDir, "a.txt")));
-        Assert.True(File.Exists(Path.Combine(outDir, "b.txt")));
-    }
-
-    
-    public void ExtractToDirectory_ZipWithSubdirectory_DirectoryStructurePreserved() {
-        string zipPath = CreateZipWithEncoding("subdir.zip", new UTF8Encoding(false, true),
-            ("subdir/nested.txt", "nested content"));
-        string outDir = Path.Combine(_tempDir, "out_subdir");
-
-        FileUtils.ExtractToDirectory(zipPath, outDir);
-
-        string nestedFile = Path.Combine(outDir, "subdir", "nested.txt");
-        Assert.True(File.Exists(nestedFile));
-        Assert.Equal("nested content", ReadFile(nestedFile));
-    }
-
-    
-    public void ExtractToDirectory_OutputDirectoryAutoCreated() {
-        string zipPath = CreateZipWithEncoding("autocreate.zip", new UTF8Encoding(false, true),
-            ("f.txt", "x"));
-        string outDir = Path.Combine(_tempDir, "nonexistent", "deep", "dir");
-
-        FileUtils.ExtractToDirectory(zipPath, outDir);
-
-        Assert.True(Directory.Exists(outDir));
-    }
-
-    
-    public void ExtractToDirectory_OverwritesExistingFile() {
-        string zipPath = CreateZipWithEncoding("overwrite.zip", new UTF8Encoding(false, true),
-            ("f.txt", "new content"));
-        string outDir = Path.Combine(_tempDir, "out_overwrite");
-        Directory.CreateDirectory(outDir);
-        File.WriteAllText(Path.Combine(outDir, "f.txt"), "old content");
-
-        FileUtils.ExtractToDirectory(zipPath, outDir);
-
-        Assert.Equal("new content", ReadFile(Path.Combine(outDir, "f.txt")));
-    }
-
-    
-    public void ExtractToDirectory_ZipSlip_ThrowsUnauthorizedAccessException() {
-        // 手动构造一个包含路径穿越条目(../../evil.txt)的 zip
-        string zipPath = Path.Combine(_tempDir, "zipslip.zip");
-        using (var stream = File.Create(zipPath))
-        using (var archive = new ZipArchive(stream, ZipArchiveMode.Create, leaveOpen: false, new UTF8Encoding(false, true))) {
-            var entry = archive.CreateEntry("../../evil.txt");
-            using var writer = new StreamWriter(entry.Open());
-            writer.Write("pwned");
-        }
-        string outDir = Path.Combine(_tempDir, "out_zipslip");
-        Directory.CreateDirectory(outDir);
-
-        Assert.Throws<UnauthorizedAccessException>(() => FileUtils.ExtractToDirectory(zipPath, outDir));
-    }
-
-    
-    public void ExtractToDirectory_GzFile_ExtractsInnerFile() {
-        const string innerContent = "gzip content";
-        const string innerFileName = "inner.txt";
-        string gzPath = CreateGzFile(innerFileName, innerContent);
-        string outDir = Path.Combine(_tempDir, "out_gz");
-
-        FileUtils.ExtractToDirectory(gzPath, outDir);
-
-        string extractedFile = Path.Combine(outDir, innerFileName);
-        Assert.True(File.Exists(extractedFile));
-        Assert.Equal(innerContent, ReadFile(extractedFile));
-    }
-
-    
-    public void ExtractToDirectory_JarFile_ExtractsAsZip() {
-        // jar 文件实际上是 zip 格式
-        string zipPath = CreateZipWithEncoding("app.jar", new UTF8Encoding(false, true),
-            ("META-INF/MANIFEST.MF", "Manifest-Version: 1.0\r\n"));
-        string outDir = Path.Combine(_tempDir, "out_jar");
-
-        FileUtils.ExtractToDirectory(zipPath, outDir);
-
-        Assert.True(File.Exists(Path.Combine(outDir, "META-INF", "MANIFEST.MF")));
-    }
-
-    #endregion
-
     #region CreateZipFromDirectory 测试