mirror of
https://github.com/adamhathcock/sharpcompress.git
synced 2026-09-23 07:25:11 +00:00
Move path handling for extraction to be common
Reader and Archive now share more extraction logic
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
using System.IO;
|
||||
using SharpCompress.Common;
|
||||
using SharpCompress.IO;
|
||||
using SharpCompress.Readers;
|
||||
|
||||
namespace SharpCompress.Archives
|
||||
{
|
||||
@@ -46,50 +45,8 @@ namespace SharpCompress.Archives
|
||||
public static void WriteToDirectory(this IArchiveEntry entry, string destinationDirectory,
|
||||
ExtractionOptions options = null)
|
||||
{
|
||||
string destinationFileName;
|
||||
string file = Path.GetFileName(entry.Key);
|
||||
string fullDestinationDirectoryPath = Path.GetFullPath(destinationDirectory);
|
||||
|
||||
options = options ?? new ExtractionOptions()
|
||||
{
|
||||
Overwrite = true
|
||||
};
|
||||
|
||||
|
||||
if (options.ExtractFullPath)
|
||||
{
|
||||
string folder = Path.GetDirectoryName(entry.Key);
|
||||
string destdir = Path.GetFullPath(
|
||||
Path.Combine(fullDestinationDirectoryPath, folder)
|
||||
);
|
||||
|
||||
if (!Directory.Exists(destdir))
|
||||
{
|
||||
if (!destdir.StartsWith(fullDestinationDirectoryPath))
|
||||
{
|
||||
throw new ExtractionException("Entry is trying to create a directory outside of the destination directory.");
|
||||
}
|
||||
|
||||
Directory.CreateDirectory(destdir);
|
||||
}
|
||||
destinationFileName = Path.Combine(destdir, file);
|
||||
}
|
||||
else
|
||||
{
|
||||
destinationFileName = Path.Combine(fullDestinationDirectoryPath, file);
|
||||
}
|
||||
|
||||
if (!entry.IsDirectory)
|
||||
{
|
||||
destinationFileName = Path.GetFullPath(destinationFileName);
|
||||
|
||||
if (!destinationFileName.StartsWith(fullDestinationDirectoryPath))
|
||||
{
|
||||
throw new ExtractionException("Entry is trying to write a file outside of the destination directory.");
|
||||
}
|
||||
|
||||
entry.WriteToFile(destinationFileName, options);
|
||||
}
|
||||
ExtractionMethods.WriteEntryToDirectory(entry, destinationDirectory, options,
|
||||
entry.WriteToFile);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -98,23 +55,15 @@ namespace SharpCompress.Archives
|
||||
public static void WriteToFile(this IArchiveEntry entry, string destinationFileName,
|
||||
ExtractionOptions options = null)
|
||||
{
|
||||
FileMode fm = FileMode.Create;
|
||||
options = options ?? new ExtractionOptions()
|
||||
{
|
||||
Overwrite = true
|
||||
};
|
||||
|
||||
|
||||
if (!options.Overwrite)
|
||||
{
|
||||
fm = FileMode.CreateNew;
|
||||
}
|
||||
using (FileStream fs = File.Open(destinationFileName, fm))
|
||||
{
|
||||
entry.WriteTo(fs);
|
||||
}
|
||||
|
||||
entry.PreserveExtractionOptions(destinationFileName, options);
|
||||
|
||||
ExtractionMethods.WriteEntryToFile(entry, destinationFileName, options,
|
||||
(x, fm) =>
|
||||
{
|
||||
using (FileStream fs = File.Open(destinationFileName, fm))
|
||||
{
|
||||
entry.WriteTo(fs);
|
||||
}
|
||||
});
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#if !NO_FILE
|
||||
using System.Linq;
|
||||
using SharpCompress.Readers;
|
||||
using SharpCompress.Common;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
87
src/SharpCompress/Common/ExtractionMethods.cs
Normal file
87
src/SharpCompress/Common/ExtractionMethods.cs
Normal file
@@ -0,0 +1,87 @@
|
||||
#if !NO_FILE
|
||||
using System;
|
||||
using System.IO;
|
||||
#endif
|
||||
|
||||
namespace SharpCompress.Common
|
||||
{
|
||||
internal static class ExtractionMethods
|
||||
{
|
||||
|
||||
#if !NO_FILE
|
||||
/// <summary>
|
||||
/// Extract to specific directory, retaining filename
|
||||
/// </summary>
|
||||
public static void WriteEntryToDirectory(IEntry entry, string destinationDirectory,
|
||||
ExtractionOptions options, Action<string, ExtractionOptions> write)
|
||||
{
|
||||
string destinationFileName;
|
||||
string file = Path.GetFileName(entry.Key);
|
||||
string fullDestinationDirectoryPath = Path.GetFullPath(destinationDirectory);
|
||||
|
||||
options = options ?? new ExtractionOptions()
|
||||
{
|
||||
Overwrite = true
|
||||
};
|
||||
|
||||
if (options.ExtractFullPath)
|
||||
{
|
||||
string folder = Path.GetDirectoryName(entry.Key);
|
||||
string destdir = Path.GetFullPath(
|
||||
Path.Combine(fullDestinationDirectoryPath, folder)
|
||||
);
|
||||
|
||||
if (!Directory.Exists(destdir))
|
||||
{
|
||||
if (!destdir.StartsWith(fullDestinationDirectoryPath))
|
||||
{
|
||||
throw new ExtractionException("Entry is trying to create a directory outside of the destination directory.");
|
||||
}
|
||||
|
||||
Directory.CreateDirectory(destdir);
|
||||
}
|
||||
destinationFileName = Path.Combine(destdir, file);
|
||||
}
|
||||
else
|
||||
{
|
||||
destinationFileName = Path.Combine(fullDestinationDirectoryPath, file);
|
||||
|
||||
}
|
||||
|
||||
if (!entry.IsDirectory)
|
||||
{
|
||||
destinationFileName = Path.GetFullPath(destinationFileName);
|
||||
|
||||
if (!destinationFileName.StartsWith(fullDestinationDirectoryPath))
|
||||
{
|
||||
throw new ExtractionException("Entry is trying to write a file outside of the destination directory.");
|
||||
}
|
||||
write(destinationFileName, options);
|
||||
}
|
||||
else if (options.ExtractFullPath && !Directory.Exists(destinationFileName))
|
||||
{
|
||||
Directory.CreateDirectory(destinationFileName);
|
||||
}
|
||||
}
|
||||
|
||||
public static void WriteEntryToFile(IEntry entry, string destinationFileName,
|
||||
ExtractionOptions options,
|
||||
Action<string, FileMode> openAndWrite)
|
||||
{
|
||||
FileMode fm = FileMode.Create;
|
||||
options = options ?? new ExtractionOptions()
|
||||
{
|
||||
Overwrite = true
|
||||
};
|
||||
|
||||
if (!options.Overwrite)
|
||||
{
|
||||
fm = FileMode.CreateNew;
|
||||
}
|
||||
|
||||
openAndWrite(destinationFileName, fm);
|
||||
entry.PreserveExtractionOptions(destinationFileName, options);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace SharpCompress.Readers
|
||||
namespace SharpCompress.Common
|
||||
{
|
||||
public class ExtractionOptions
|
||||
{
|
||||
@@ -42,36 +42,8 @@ namespace SharpCompress.Readers
|
||||
public static void WriteEntryToDirectory(this IReader reader, string destinationDirectory,
|
||||
ExtractionOptions options = null)
|
||||
{
|
||||
string destinationFileName = string.Empty;
|
||||
string file = Path.GetFileName(reader.Entry.Key);
|
||||
options = options ?? new ExtractionOptions()
|
||||
{
|
||||
Overwrite = true
|
||||
};
|
||||
|
||||
if (options.ExtractFullPath)
|
||||
{
|
||||
string folder = Path.GetDirectoryName(reader.Entry.Key);
|
||||
string destdir = Path.Combine(destinationDirectory, folder);
|
||||
if (!Directory.Exists(destdir))
|
||||
{
|
||||
Directory.CreateDirectory(destdir);
|
||||
}
|
||||
destinationFileName = Path.Combine(destdir, file);
|
||||
}
|
||||
else
|
||||
{
|
||||
destinationFileName = Path.Combine(destinationDirectory, file);
|
||||
}
|
||||
|
||||
if (!reader.Entry.IsDirectory)
|
||||
{
|
||||
reader.WriteEntryToFile(destinationFileName, options);
|
||||
}
|
||||
else if (options.ExtractFullPath && !Directory.Exists(destinationFileName))
|
||||
{
|
||||
Directory.CreateDirectory(destinationFileName);
|
||||
}
|
||||
ExtractionMethods.WriteEntryToDirectory(reader.Entry, destinationDirectory, options,
|
||||
reader.WriteEntryToFile);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -80,21 +52,14 @@ namespace SharpCompress.Readers
|
||||
public static void WriteEntryToFile(this IReader reader, string destinationFileName,
|
||||
ExtractionOptions options = null)
|
||||
{
|
||||
FileMode fm = FileMode.Create;
|
||||
options = options ?? new ExtractionOptions()
|
||||
{
|
||||
Overwrite = true
|
||||
};
|
||||
|
||||
if (!options.Overwrite)
|
||||
{
|
||||
fm = FileMode.CreateNew;
|
||||
}
|
||||
using (FileStream fs = File.Open(destinationFileName, fm))
|
||||
{
|
||||
reader.WriteEntryTo(fs);
|
||||
}
|
||||
reader.Entry.PreserveExtractionOptions(destinationFileName, options);
|
||||
ExtractionMethods.WriteEntryToFile(reader.Entry, destinationFileName, options,
|
||||
(x, fm) =>
|
||||
{
|
||||
using (FileStream fs = File.Open(destinationFileName, fm))
|
||||
{
|
||||
reader.WriteEntryTo(fs);
|
||||
}
|
||||
});
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user