public void InvalidPaths_Throw() { Assert.Throws <ArgumentNullException>(() => TarFile.ExtractToDirectory(sourceFileName: null, destinationDirectoryName: "path", overwriteFiles: false)); Assert.Throws <ArgumentException>(() => TarFile.ExtractToDirectory(sourceFileName: string.Empty, destinationDirectoryName: "path", overwriteFiles: false)); Assert.Throws <ArgumentNullException>(() => TarFile.ExtractToDirectory(sourceFileName: "path", destinationDirectoryName: null, overwriteFiles: false)); Assert.Throws <ArgumentException>(() => TarFile.ExtractToDirectory(sourceFileName: "path", destinationDirectoryName: string.Empty, overwriteFiles: false)); }
public void Extract_Archive_File_OverwriteTrue() { string testCaseName = "file"; string archivePath = GetTarFilePath(CompressionMethod.Uncompressed, TestTarFormat.pax, testCaseName); using TempDirectory destination = new TempDirectory(); string filePath = Path.Join(destination.Path, "file.txt"); using (FileStream fileStream = File.Create(filePath)) { using StreamWriter writer = new StreamWriter(fileStream, leaveOpen: false); writer.WriteLine("Original text"); } TarFile.ExtractToDirectory(archivePath, destination.Path, overwriteFiles: true); Assert.True(File.Exists(filePath)); using (FileStream fileStream = File.Open(filePath, FileMode.Open)) { using StreamReader reader = new StreamReader(fileStream); string actualContents = reader.ReadLine(); Assert.Equal($"Hello {testCaseName}", actualContents); // Confirm overwrite } }
// This test would not pass for the V7 and Ustar formats in some OSs like MacCatalyst, tvOSSimulator and OSX, because the TempDirectory gets created in // a folder with a path longer than 100 bytes, and those tar formats have no way of handling pathnames and linknames longer than that length. // The rest of the OSs create the TempDirectory in a path that does not surpass the 100 bytes, so the 'subfolder' parameter gives a chance to extend // the base directory past that length, to ensure this scenario is tested everywhere. private void Extract_LinkEntry_TargetInsideDirectory_Internal(TarEntryType entryType, TarEntryFormat format, string subfolder) { using TempDirectory root = new TempDirectory(); string baseDir = string.IsNullOrEmpty(subfolder) ? root.Path : Path.Join(root.Path, subfolder); Directory.CreateDirectory(baseDir); string linkName = "link"; string targetName = "target"; string targetPath = Path.Join(baseDir, targetName); File.Create(targetPath).Dispose(); using MemoryStream archive = new MemoryStream(); using (TarWriter writer = new TarWriter(archive, format, leaveOpen: true)) { TarEntry entry = InvokeTarEntryCreationConstructor(format, entryType, linkName); entry.LinkName = targetPath; writer.WriteEntry(entry); } archive.Seek(0, SeekOrigin.Begin); TarFile.ExtractToDirectory(archive, baseDir, overwriteFiles: false); Assert.Equal(2, Directory.GetFileSystemEntries(baseDir).Count()); }
public void SetsLastModifiedTimeOnExtractedFiles() { using TempDirectory root = new TempDirectory(); string inDir = Path.Join(root.Path, "indir"); string inFile = Path.Join(inDir, "file"); string tarFile = Path.Join(root.Path, "file.tar"); string outDir = Path.Join(root.Path, "outdir"); string outFile = Path.Join(outDir, "file"); Directory.CreateDirectory(inDir); File.Create(inFile).Dispose(); var dt = new DateTime(2001, 1, 2, 3, 4, 5, DateTimeKind.Local); File.SetLastWriteTime(inFile, dt); TarFile.CreateFromDirectory(sourceDirectoryName: inDir, destinationFileName: tarFile, includeBaseDirectory: false); Directory.CreateDirectory(outDir); TarFile.ExtractToDirectory(sourceFileName: tarFile, destinationDirectoryName: outDir, overwriteFiles: false); Assert.True(File.Exists(outFile)); Assert.InRange(File.GetLastWriteTime(outFile).Ticks, dt.AddSeconds(-3).Ticks, dt.AddSeconds(3).Ticks); // include some slop for filesystem granularity }
public void ExtractEntry_ManySubfolderSegments_NoPrecedingDirectoryEntries() { using TempDirectory root = new TempDirectory(); string firstSegment = "a"; string secondSegment = Path.Join(firstSegment, "b"); string fileWithTwoSegments = Path.Join(secondSegment, "c.txt"); using MemoryStream archive = new MemoryStream(); using (TarWriter writer = new TarWriter(archive, TarFormat.Ustar, leaveOpen: true)) { // No preceding directory entries for the segments UstarTarEntry entry = new UstarTarEntry(TarEntryType.RegularFile, fileWithTwoSegments); entry.DataStream = new MemoryStream(); entry.DataStream.Write(new byte[] { 0x1 }); entry.DataStream.Seek(0, SeekOrigin.Begin); writer.WriteEntry(entry); } archive.Seek(0, SeekOrigin.Begin); TarFile.ExtractToDirectory(archive, root.Path, overwriteFiles: false); Assert.True(Directory.Exists(Path.Join(root.Path, firstSegment))); Assert.True(Directory.Exists(Path.Join(root.Path, secondSegment))); Assert.True(File.Exists(Path.Join(root.Path, fileWithTwoSegments))); }
public void Extract_AllSegmentsOfPath() { using TempDirectory source = new TempDirectory(); using TempDirectory destination = new TempDirectory(); string archivePath = Path.Join(source.Path, "archive.tar"); using FileStream archiveStream = File.Create(archivePath); using (TarWriter writer = new TarWriter(archiveStream)) { PaxTarEntry segment1 = new PaxTarEntry(TarEntryType.Directory, "segment1"); writer.WriteEntry(segment1); PaxTarEntry segment2 = new PaxTarEntry(TarEntryType.Directory, "segment1/segment2"); writer.WriteEntry(segment2); PaxTarEntry file = new PaxTarEntry(TarEntryType.RegularFile, "segment1/segment2/file.txt"); writer.WriteEntry(file); } TarFile.ExtractToDirectory(archivePath, destination.Path, overwriteFiles: false); string segment1Path = Path.Join(destination.Path, "segment1"); Assert.True(Directory.Exists(segment1Path), $"{segment1Path}' does not exist."); string segment2Path = Path.Join(segment1Path, "segment2"); Assert.True(Directory.Exists(segment2Path), $"{segment2Path}' does not exist."); string filePath = Path.Join(segment2Path, "file.txt"); Assert.True(File.Exists(filePath), $"{filePath}' does not exist."); }
public void Extract_UnseekableStream_BlockAlignmentPadding_DoesNotAffectNextEntries(int contentSize) { byte[] fileContents = new byte[contentSize]; Array.Fill <byte>(fileContents, 0x1); using var archive = new MemoryStream(); using (var compressor = new GZipStream(archive, CompressionMode.Compress, leaveOpen: true)) { using var writer = new TarWriter(compressor); var entry1 = new PaxTarEntry(TarEntryType.RegularFile, "file"); entry1.DataStream = new MemoryStream(fileContents); writer.WriteEntry(entry1); var entry2 = new PaxTarEntry(TarEntryType.RegularFile, "next-file"); writer.WriteEntry(entry2); } archive.Position = 0; using var decompressor = new GZipStream(archive, CompressionMode.Decompress); using var reader = new TarReader(decompressor); using TempDirectory destination = new TempDirectory(); TarFile.ExtractToDirectory(decompressor, destination.Path, overwriteFiles: true); Assert.Equal(2, Directory.GetFileSystemEntries(destination.Path, "*", SearchOption.AllDirectories).Count()); }
public void NonExistentDirectory_Throws() { using TempDirectory root = new TempDirectory(); string dirPath = Path.Join(root.Path, "dir"); using MemoryStream archive = new MemoryStream(); Assert.Throws <DirectoryNotFoundException>(() => TarFile.ExtractToDirectory(archive, destinationDirectoryName: dirPath, overwriteFiles: false)); }
public void NonExistentDirectory_Throws() { using TempDirectory root = new TempDirectory(); string filePath = Path.Join(root.Path, "file.tar"); string dirPath = Path.Join(root.Path, "dir"); File.Create(filePath).Dispose(); Assert.Throws <DirectoryNotFoundException>(() => TarFile.ExtractToDirectory(sourceFileName: filePath, destinationDirectoryName: dirPath, overwriteFiles: false)); }
public void Extract_Archive_File_OverwriteFalse() { string sourceArchiveFileName = GetTarFilePath(CompressionMethod.Uncompressed, TestTarFormat.pax, "file"); using TempDirectory destination = new TempDirectory(); string filePath = Path.Join(destination.Path, "file.txt"); File.Create(filePath).Dispose(); Assert.Throws <IOException>(() => TarFile.ExtractToDirectory(sourceArchiveFileName, destination.Path, overwriteFiles: false)); }
public void Extract_Archive_File(TestTarFormat testFormat) { string sourceArchiveFileName = GetTarFilePath(CompressionMethod.Uncompressed, testFormat, "file"); using TempDirectory destination = new TempDirectory(); string filePath = Path.Join(destination.Path, "file.txt"); TarFile.ExtractToDirectory(sourceArchiveFileName, destination.Path, overwriteFiles: false); Assert.True(File.Exists(filePath)); }
public void Extract_Archive_File_OverwriteFalse() { string sourceArchiveFileName = GetTarFilePath(CompressionMethod.Uncompressed, TestTarFormat.pax, "file"); using TempDirectory destination = new TempDirectory(); string filePath = Path.Join(destination.Path, "file.txt"); using (StreamWriter writer = File.CreateText(filePath)) { writer.WriteLine("My existence should cause an exception"); } Assert.Throws <IOException>(() => TarFile.ExtractToDirectory(sourceArchiveFileName, destination.Path, overwriteFiles: false)); }
public void Extract_SpecialFiles_Unix_Unelevated_ThrowsUnauthorizedAccess() { string originalFileName = GetTarFilePath(CompressionMethod.Uncompressed, TestTarFormat.ustar, "specialfiles"); using TempDirectory root = new TempDirectory(); string archive = Path.Join(root.Path, "input.tar"); string destination = Path.Join(root.Path, "dir"); // Copying the tar to reduce the chance of other tests failing due to being used by another process File.Copy(originalFileName, archive); Directory.CreateDirectory(destination); Assert.Throws<UnauthorizedAccessException>(() => TarFile.ExtractToDirectory(archive, destination, overwriteFiles: false)); Assert.Equal(0, Directory.GetFileSystemEntries(destination).Count()); }
public void Extract_LinkEntry_TargetOutsideDirectory(TarEntryType entryType) { using MemoryStream archive = new MemoryStream(); using (TarWriter writer = new TarWriter(archive, TarFormat.Ustar, leaveOpen: true)) { UstarTarEntry entry = new UstarTarEntry(entryType, "link"); entry.LinkName = PlatformDetection.IsWindows ? @"C:\Windows\System32\notepad.exe" : "/usr/bin/nano"; writer.WriteEntry(entry); } archive.Seek(0, SeekOrigin.Begin); using TempDirectory root = new TempDirectory(); Assert.Throws <IOException>(() => TarFile.ExtractToDirectory(archive, root.Path, overwriteFiles: false)); Assert.Equal(0, Directory.GetFileSystemEntries(root.Path).Count()); }
public void UnixFileModes_RestrictiveParentDir(bool overwrite) { using TempDirectory source = new TempDirectory(); using TempDirectory destination = new TempDirectory(); string archivePath = Path.Join(source.Path, "archive.tar"); using FileStream archiveStream = File.Create(archivePath); using (TarWriter writer = new TarWriter(archiveStream)) { PaxTarEntry dir = new PaxTarEntry(TarEntryType.Directory, "dir"); dir.Mode = UnixFileMode.None; // Restrict permissions. writer.WriteEntry(dir); PaxTarEntry file = new PaxTarEntry(TarEntryType.RegularFile, "dir/file"); file.Mode = TestPermission1; writer.WriteEntry(file); } string dirPath = Path.Join(destination.Path, "dir"); string filePath = Path.Join(dirPath, "file"); if (overwrite) { Directory.CreateDirectory(dirPath); File.OpenWrite(filePath).Dispose(); } TarFile.ExtractToDirectory(archivePath, destination.Path, overwriteFiles: overwrite); Assert.True(Directory.Exists(dirPath), $"{dirPath}' does not exist."); AssertFileModeEquals(dirPath, UnixFileMode.None); // Set dir permissions so we can access file. SetUnixFileMode(dirPath, UserAll); Assert.True(File.Exists(filePath), $"{filePath}' does not exist."); AssertFileModeEquals(filePath, TestPermission1); }
public void ExtractArchiveWithEntriesThatStartWithSlashDotPrefix() { using TempDirectory root = new TempDirectory(); using MemoryStream archiveStream = GetStrangeTarMemoryStream("prefixDotSlashAndCurrentFolderEntry"); TarFile.ExtractToDirectory(archiveStream, root.Path, overwriteFiles: true); archiveStream.Position = 0; using TarReader reader = new TarReader(archiveStream, leaveOpen: false); TarEntry entry; while ((entry = reader.GetNextEntry()) != null) { // Normalize the path (remove redundant segments), remove trailing separators // this is so the first entry can be skipped if it's the same as the root directory string entryPath = Path.TrimEndingDirectorySeparator(Path.GetFullPath(Path.Join(root.Path, entry.Name))); Assert.True(Path.Exists(entryPath), $"Entry was not extracted: {entryPath}"); } }
public void TarGz_TarFile_CreateFromDir_ExtractToDir() { using TempDirectory root = new TempDirectory(); string archivePath = Path.Join(root.Path, "compressed.tar.gz"); string sourceDirectory = Path.Join(root.Path, "source"); Directory.CreateDirectory(sourceDirectory); string destinationDirectory = Path.Join(root.Path, "destination"); Directory.CreateDirectory(destinationDirectory); string fileName = "file.txt"; string filePath = Path.Join(sourceDirectory, fileName); File.Create(filePath).Dispose(); using (FileStream streamToCompress = File.Create(archivePath)) { using GZipStream compressorStream = new GZipStream(streamToCompress, CompressionMode.Compress); TarFile.CreateFromDirectory(sourceDirectory, compressorStream, includeBaseDirectory: false); } FileInfo fileInfo = new FileInfo(archivePath); Assert.True(fileInfo.Exists); Assert.True(fileInfo.Length > 0); using (FileStream streamToDecompress = File.OpenRead(archivePath)) { using GZipStream decompressorStream = new GZipStream(streamToDecompress, CompressionMode.Decompress); TarFile.ExtractToDirectory(decompressorStream, destinationDirectory, overwriteFiles: true); Assert.True(File.Exists(filePath)); } }
private void Extract_LinkEntry_TargetInsideDirectory_Internal(TarEntryType entryType) { using TempDirectory root = new TempDirectory(); string linkName = "link"; string targetName = "target"; string targetPath = Path.Join(root.Path, targetName); File.Create(targetPath).Dispose(); using MemoryStream archive = new MemoryStream(); using (TarWriter writer = new TarWriter(archive, TarFormat.Ustar, leaveOpen: true)) { UstarTarEntry entry = new UstarTarEntry(entryType, linkName); entry.LinkName = targetPath; writer.WriteEntry(entry); } archive.Seek(0, SeekOrigin.Begin); TarFile.ExtractToDirectory(archive, root.Path, overwriteFiles: false); Assert.Equal(2, Directory.GetFileSystemEntries(root.Path).Count()); }
public void UnixFileModes(bool overwrite) { using TempDirectory source = new TempDirectory(); using TempDirectory destination = new TempDirectory(); string archivePath = Path.Join(source.Path, "archive.tar"); using FileStream archiveStream = File.Create(archivePath); using (TarWriter writer = new TarWriter(archiveStream)) { PaxTarEntry dir = new PaxTarEntry(TarEntryType.Directory, "dir"); dir.Mode = TestPermission1; writer.WriteEntry(dir); PaxTarEntry file = new PaxTarEntry(TarEntryType.RegularFile, "file"); file.Mode = TestPermission2; writer.WriteEntry(file); // Archive has no entry for missing_parent. PaxTarEntry missingParentDir = new PaxTarEntry(TarEntryType.Directory, "missing_parent/dir"); missingParentDir.Mode = TestPermission3; writer.WriteEntry(missingParentDir); // out_of_order_parent/file entry comes before out_of_order_parent entry. PaxTarEntry outOfOrderFile = new PaxTarEntry(TarEntryType.RegularFile, "out_of_order_parent/file"); writer.WriteEntry(outOfOrderFile); PaxTarEntry outOfOrderDir = new PaxTarEntry(TarEntryType.Directory, "out_of_order_parent"); outOfOrderDir.Mode = TestPermission4; writer.WriteEntry(outOfOrderDir); } string dirPath = Path.Join(destination.Path, "dir"); string filePath = Path.Join(destination.Path, "file"); string missingParentPath = Path.Join(destination.Path, "missing_parent"); string missingParentDirPath = Path.Join(missingParentPath, "dir"); string outOfOrderDirPath = Path.Join(destination.Path, "out_of_order_parent"); if (overwrite) { File.OpenWrite(filePath).Dispose(); Directory.CreateDirectory(dirPath); Directory.CreateDirectory(missingParentDirPath); Directory.CreateDirectory(outOfOrderDirPath); } TarFile.ExtractToDirectory(archivePath, destination.Path, overwriteFiles: overwrite); Assert.True(Directory.Exists(dirPath), $"{dirPath}' does not exist."); AssertFileModeEquals(dirPath, TestPermission1); Assert.True(File.Exists(filePath), $"{filePath}' does not exist."); AssertFileModeEquals(filePath, TestPermission2); // Missing parents are created with CreateDirectoryDefaultMode. Assert.True(Directory.Exists(missingParentPath), $"{missingParentPath}' does not exist."); AssertFileModeEquals(missingParentPath, CreateDirectoryDefaultMode); Assert.True(Directory.Exists(missingParentDirPath), $"{missingParentDirPath}' does not exist."); AssertFileModeEquals(missingParentDirPath, TestPermission3); // Directory modes that are out-of-order are still applied. Assert.True(Directory.Exists(outOfOrderDirPath), $"{outOfOrderDirPath}' does not exist."); AssertFileModeEquals(outOfOrderDirPath, TestPermission4); }
public void UnreadableStream_Throws() { using MemoryStream archive = new MemoryStream(); using WrappedStream unreadable = new WrappedStream(archive, canRead: false, canWrite: true, canSeek: true); Assert.Throws <IOException>(() => TarFile.ExtractToDirectory(unreadable, destinationDirectoryName: "path", overwriteFiles: false)); }
public void InvalidPath_Throws() { using MemoryStream archive = new MemoryStream(); Assert.Throws <ArgumentNullException>(() => TarFile.ExtractToDirectory(archive, destinationDirectoryName: null, overwriteFiles: false)); Assert.Throws <ArgumentException>(() => TarFile.ExtractToDirectory(archive, destinationDirectoryName: string.Empty, overwriteFiles: false)); }
public void NullStream_Throws() { Assert.Throws <ArgumentNullException>(() => TarFile.ExtractToDirectory(source: null, destinationDirectoryName: "path", overwriteFiles: false)); }
/// <summary> /// Upgrade the package, with the understanding that it is located in the Asset database. /// </summary> private static void UpgradeAssetDatabase() { // Get a temporary file // TODO: This will need to be changed for newer .NET (System.IO.GetTempFileName()) string tempFile = Path.GetTempFileName(); // Download the file EditorUtility.DisplayProgressBar("GDX", "Downloading Update ...", 0.25f); try { #if UNITY_2020_2_OR_NEWER using WebClient webClient = new WebClient(); webClient.DownloadFile(GitHubLatestUri + UpdatePackageDefinition.version + ".tar.gz", tempFile); #else using (WebClient webClient = new WebClient()) { webClient.DownloadFile(GitHubLatestUri + UpdatePackageDefinition.version + ".tar.gz", tempFile); } #endif } catch (Exception e) { // We will end up here if the formulated Uri is bad. Debug.LogWarning(e.Message); return; } finally { EditorUtility.ClearProgressBar(); } string tempExtractFolder = Path.Combine(Path.GetTempPath(), PackageProvider.PackageName); // Remove previous upgrade folder (if it exists) if (Directory.Exists(tempExtractFolder)) { Directory.Delete(tempExtractFolder, true); } Platform.EnsureFolderHierarchyExists(tempExtractFolder); // Extract downloaded tarball to the temp folder TarFile.ExtractToDirectory(tempFile, tempExtractFolder, true); // Get desired target placement string targetPath = Path.GetDirectoryName(LocalPackage.PackageManifestPath); // Handle VCS if (Provider.enabled && Provider.isActive) { AssetList checkoutAssets = VersionControl.GetAssetListFromFolder(targetPath); Task checkoutTask = Provider.Checkout(checkoutAssets, CheckoutMode.Both); checkoutTask.Wait(); } // Remove all existing content if (targetPath != null) { try { AssetDatabase.StartAssetEditing(); Directory.Delete(targetPath, true); // Drop in new content Directory.Move( Path.Combine(tempExtractFolder, "GDX-" + UpdatePackageDefinition.version), targetPath); AssetDatabase.ImportAsset(LocalPackage.PackageAssetPath); } finally { AssetDatabase.StopAssetEditing(); } } }