Normalize extraction methods

This commit is contained in:
Matt Nadareski
2025-07-29 21:31:35 -04:00
parent 0725f4ba0f
commit 58b5b5228a
10 changed files with 134 additions and 57 deletions

View File

@@ -31,13 +31,23 @@ namespace BinaryObjectScanner.FileType
// Try opening the stream
using var bz2File = new BZip2InputStream(stream, true);
// Create the output file path
Directory.CreateDirectory(outDir);
string tempFile = Path.Combine(outDir, Guid.NewGuid().ToString());
// Ensure directory separators are consistent
string filename = Guid.NewGuid().ToString();
if (Path.DirectorySeparatorChar == '\\')
filename = filename.Replace('/', '\\');
else if (Path.DirectorySeparatorChar == '/')
filename = filename.Replace('\\', '/');
// Ensure the full output directory exists
filename = Path.Combine(outDir, filename);
var directoryName = Path.GetDirectoryName(filename);
if (directoryName != null && !Directory.Exists(directoryName))
Directory.CreateDirectory(directoryName);
// Extract the file
using FileStream fs = File.OpenWrite(tempFile);
using FileStream fs = File.OpenWrite(filename);
bz2File.CopyTo(fs);
fs.Flush();
return true;
}

View File

@@ -66,13 +66,21 @@ namespace BinaryObjectScanner.FileType
decoded = decoded.Replace(c, '_');
}
string tempFile = Path.Combine(outDir, decoded);
var directoryName = Path.GetDirectoryName(tempFile);
// Ensure directory separators are consistent
if (Path.DirectorySeparatorChar == '\\')
decoded = decoded.Replace('/', '\\');
else if (Path.DirectorySeparatorChar == '/')
decoded = decoded.Replace('\\', '/');
// Ensure the full output directory exists
decoded = Path.Combine(outDir, decoded);
var directoryName = Path.GetDirectoryName(decoded);
if (directoryName != null && !Directory.Exists(directoryName))
Directory.CreateDirectory(directoryName);
using Stream fs = File.OpenWrite(tempFile);
using Stream fs = File.OpenWrite(decoded);
fs.Write(strData, 0, strData.Length);
fs.Flush();
}
catch (Exception ex)
{

View File

@@ -31,13 +31,23 @@ namespace BinaryObjectScanner.FileType
// Try opening the stream
using var gzipFile = new GZipStream(stream, CompressionMode.Decompress, true);
// Create the output file path
Directory.CreateDirectory(outDir);
string tempFile = Path.Combine(outDir, Guid.NewGuid().ToString());
// Ensure directory separators are consistent
string filename = Guid.NewGuid().ToString();
if (Path.DirectorySeparatorChar == '\\')
filename = filename.Replace('/', '\\');
else if (Path.DirectorySeparatorChar == '/')
filename = filename.Replace('\\', '/');
// Ensure the full output directory exists
filename = Path.Combine(outDir, filename);
var directoryName = Path.GetDirectoryName(filename);
if (directoryName != null && !Directory.Exists(directoryName))
Directory.CreateDirectory(directoryName);
// Extract the file
using FileStream fs = File.OpenWrite(tempFile);
using FileStream fs = File.OpenWrite(filename);
gzipFile.CopyTo(fs);
fs.Flush();
return true;
}

View File

@@ -71,22 +71,20 @@ namespace BinaryObjectScanner.FileType
if (!cabfile.HeaderList.FileIsValid(i))
continue;
string tempFile;
try
{
string? filename = cabfile.HeaderList.GetFileName(i);
tempFile = Path.Combine(outDir, filename ?? string.Empty);
}
catch
{
tempFile = Path.Combine(outDir, $"BAD_FILENAME{i}");
}
// Ensure directory separators are consistent
string filename = cabfile.HeaderList.GetFileName(i) ?? $"BAD_FILENAME{i}";
if (Path.DirectorySeparatorChar == '\\')
filename = filename.Replace('/', '\\');
else if (Path.DirectorySeparatorChar == '/')
filename = filename.Replace('\\', '/');
var directoryName = Path.GetDirectoryName(tempFile);
// Ensure the full output directory exists
filename = Path.Combine(outDir, filename);
var directoryName = Path.GetDirectoryName(filename);
if (directoryName != null && !Directory.Exists(directoryName))
Directory.CreateDirectory(directoryName);
cabfile.FileSave(i, tempFile);
cabfile.FileSave(i, filename);
}
catch (Exception ex)
{

View File

@@ -56,14 +56,23 @@ namespace BinaryObjectScanner.FileType
// Loop over each entry
foreach (string sub in listfileLines)
{
// Ensure directory separators are consistent
string filename = sub;
if (Path.DirectorySeparatorChar == '\\')
filename = filename.Replace('/', '\\');
else if (Path.DirectorySeparatorChar == '/')
filename = filename.Replace('\\', '/');
// Ensure the full output directory exists
filename = Path.Combine(outDir, filename);
var directoryName = Path.GetDirectoryName(filename);
if (directoryName != null && !Directory.Exists(directoryName))
Directory.CreateDirectory(directoryName);
// Try to write the data
try
{
string tempFile = Path.Combine(outDir, sub);
var directoryName = Path.GetDirectoryName(tempFile);
if (directoryName != null && !Directory.Exists(directoryName))
Directory.CreateDirectory(directoryName);
mpqArchive.ExtractFile(sub, tempFile);
mpqArchive.ExtractFile(sub, filename);
}
catch (System.Exception ex)
{

View File

@@ -64,12 +64,20 @@ namespace BinaryObjectScanner.FileType
if (!entry.IsComplete)
continue;
string tempFile = Path.Combine(outDir, entry.Key);
var directoryName = Path.GetDirectoryName(tempFile);
// Ensure directory separators are consistent
string filename = entry.Key;
if (Path.DirectorySeparatorChar == '\\')
filename = filename.Replace('/', '\\');
else if (Path.DirectorySeparatorChar == '/')
filename = filename.Replace('\\', '/');
// Ensure the full output directory exists
filename = Path.Combine(outDir, filename);
var directoryName = Path.GetDirectoryName(filename);
if (directoryName != null && !Directory.Exists(directoryName))
Directory.CreateDirectory(directoryName);
entry.WriteToFile(tempFile);
entry.WriteToFile(filename);
}
catch (Exception ex)
{

View File

@@ -67,14 +67,14 @@ namespace BinaryObjectScanner.FileType
return false;
#endif
}
#if NET462_OR_GREATER || NETCOREAPP
/// <summary>
/// Extraction method for non-solid archives. This iterates over each entry in the archive to extract every
/// file individually, in order to extract all valid files from the archive.
/// </summary>
private bool ExtractNonSolid(RarArchive rarFile, string outDir, bool includeDebug)
private static bool ExtractNonSolid(RarArchive rarFile, string outDir, bool includeDebug)
{
foreach (var entry in rarFile.Entries)
{
@@ -92,12 +92,20 @@ namespace BinaryObjectScanner.FileType
if (!entry.IsComplete)
continue;
string tempFile = Path.Combine(outDir, entry.Key);
var directoryName = Path.GetDirectoryName(tempFile);
// Ensure directory separators are consistent
string filename = entry.Key;
if (Path.DirectorySeparatorChar == '\\')
filename = filename.Replace('/', '\\');
else if (Path.DirectorySeparatorChar == '/')
filename = filename.Replace('\\', '/');
// Ensure the full output directory exists
filename = Path.Combine(outDir, filename);
var directoryName = Path.GetDirectoryName(filename);
if (directoryName != null && !Directory.Exists(directoryName))
Directory.CreateDirectory(directoryName);
entry.WriteToFile(tempFile);
entry.WriteToFile(filename);
}
catch (Exception ex)
{
@@ -106,12 +114,12 @@ namespace BinaryObjectScanner.FileType
}
return true;
}
/// <summary>
/// Extraction method for solid archives. Uses ExtractAllEntries because extraction for solid archives must be
/// done sequentially, and files beyond a corrupted point in a solid archive will be unreadable anyways.
/// </summary>
private bool ExtractSolid(RarArchive rarFile, string outDir, bool includeDebug)
private static bool ExtractSolid(RarArchive rarFile, string outDir, bool includeDebug)
{
try
{

View File

@@ -65,13 +65,13 @@ namespace BinaryObjectScanner.FileType
return false;
#endif
}
#if NET462_OR_GREATER || NETCOREAPP
/// <summary>
/// Extraction method for non-solid archives. This iterates over each entry in the archive to extract every
/// file individually, in order to extract all valid files from the archive.
/// </summary>
private bool ExtractNonSolid(SevenZipArchive sevenZip, string outDir, bool includeDebug)
private static bool ExtractNonSolid(SevenZipArchive sevenZip, string outDir, bool includeDebug)
{
foreach (var entry in sevenZip.Entries)
{
@@ -89,12 +89,20 @@ namespace BinaryObjectScanner.FileType
if (!entry.IsComplete)
continue;
string tempFile = Path.Combine(outDir, entry.Key);
var directoryName = Path.GetDirectoryName(tempFile);
// Ensure directory separators are consistent
string filename = entry.Key;
if (Path.DirectorySeparatorChar == '\\')
filename = filename.Replace('/', '\\');
else if (Path.DirectorySeparatorChar == '/')
filename = filename.Replace('\\', '/');
// Ensure the full output directory exists
filename = Path.Combine(outDir, filename);
var directoryName = Path.GetDirectoryName(filename);
if (directoryName != null && !Directory.Exists(directoryName))
Directory.CreateDirectory(directoryName);
entry.WriteToFile(tempFile);
entry.WriteToFile(filename);
}
catch (Exception ex)
{
@@ -103,24 +111,24 @@ namespace BinaryObjectScanner.FileType
}
return true;
}
/// <summary>
/// Extraction method for solid archives. Uses ExtractAllEntries because extraction for solid archives must be
/// done sequentially, and files beyond a corrupted point in a solid archive will be unreadable anyways.
/// </summary>
private bool ExtractSolid(SevenZipArchive sevenZip, string outDir, bool includeDebug)
private static bool ExtractSolid(SevenZipArchive sevenZip, string outDir, bool includeDebug)
{
try
{
if (!Directory.Exists(outDir))
Directory.CreateDirectory(outDir);
sevenZip.WriteToDirectory(outDir, new ExtractionOptions()
{
ExtractFullPath = true,
Overwrite = true,
Overwrite = true,
});
}
catch (Exception ex)
{

View File

@@ -54,12 +54,20 @@ namespace BinaryObjectScanner.FileType
if (!entry.IsComplete)
continue;
string tempFile = Path.Combine(outDir, entry.Key);
var directoryName = Path.GetDirectoryName(tempFile);
// Ensure directory separators are consistent
string filename = entry.Key;
if (Path.DirectorySeparatorChar == '\\')
filename = filename.Replace('/', '\\');
else if (Path.DirectorySeparatorChar == '/')
filename = filename.Replace('\\', '/');
// Ensure the full output directory exists
filename = Path.Combine(outDir, filename);
var directoryName = Path.GetDirectoryName(filename);
if (directoryName != null && !Directory.Exists(directoryName))
Directory.CreateDirectory(directoryName);
entry.WriteToFile(tempFile);
entry.WriteToFile(filename);
}
catch (Exception ex)
{

View File

@@ -34,13 +34,23 @@ namespace BinaryObjectScanner.FileType
// Try opening the stream
using var xzFile = new XZStream(stream);
// Create the output file path
Directory.CreateDirectory(outDir);
string tempFile = Path.Combine(outDir, Guid.NewGuid().ToString());
// Ensure directory separators are consistent
string filename = Guid.NewGuid().ToString();
if (Path.DirectorySeparatorChar == '\\')
filename = filename.Replace('/', '\\');
else if (Path.DirectorySeparatorChar == '/')
filename = filename.Replace('\\', '/');
// Ensure the full output directory exists
filename = Path.Combine(outDir, filename);
var directoryName = Path.GetDirectoryName(filename);
if (directoryName != null && !Directory.Exists(directoryName))
Directory.CreateDirectory(directoryName);
// Extract the file
using FileStream fs = File.OpenWrite(tempFile);
using FileStream fs = File.OpenWrite(filename);
xzFile.CopyTo(fs);
fs.Flush();
return true;
}