mirror of
https://github.com/SabreTools/SabreTools.Serialization.git
synced 2026-02-03 21:30:35 +00:00
Fix ISO9660 extraction of large files (#46)
* ExtentLength is uint * Fix * fix2 * fix3 * fix4 * Invert multi extent final extent logic
This commit is contained in:
@@ -28,7 +28,7 @@ namespace SabreTools.Data.Models.ISO9660
|
||||
/// <summary>
|
||||
/// Number of bytes allocated to this extent (not including extended attribute record length)
|
||||
/// </summary>
|
||||
public BothInt32 ExtentLength { get; set; } = 0;
|
||||
public BothUInt32 ExtentLength { get; set; } = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Datetime of recording for the Directory Record
|
||||
|
||||
@@ -635,7 +635,7 @@ namespace SabreTools.Serialization.Readers
|
||||
|
||||
// Use provided extent endinanness
|
||||
int extentLocation = bigEndian ? dr.ExtentLocation.BigEndian : dr.ExtentLocation.LittleEndian;
|
||||
int extentLength = bigEndian ? dr.ExtentLength.BigEndian : dr.ExtentLength.LittleEndian;
|
||||
uint extentLength = bigEndian ? dr.ExtentLength.BigEndian : dr.ExtentLength.LittleEndian;
|
||||
long extentOffset = (long)extentLocation * (long)blockLength;
|
||||
long extentFinal = extentOffset + (long)extentLength;
|
||||
|
||||
@@ -668,7 +668,7 @@ namespace SabreTools.Serialization.Readers
|
||||
|
||||
// Read all directory records in this directory
|
||||
var records = new List<DirectoryRecord>();
|
||||
int pos = 0;
|
||||
uint pos = 0;
|
||||
while (pos < extentLength)
|
||||
{
|
||||
// Peek next byte to check whether the next record length is not greater than the end of the dir extent
|
||||
@@ -677,8 +677,8 @@ namespace SabreTools.Serialization.Readers
|
||||
// If record length of 0x00, next record begins in next sector
|
||||
if (recordLength == 0)
|
||||
{
|
||||
int paddingLength = sectorLength - (pos % sectorLength);
|
||||
pos += paddingLength;
|
||||
int paddingLength = (int)((uint)sectorLength - (pos % (uint)sectorLength));
|
||||
pos += (uint)paddingLength;
|
||||
_ = data.ReadBytes(paddingLength);
|
||||
|
||||
// Finish parsing records if end reached
|
||||
@@ -786,7 +786,7 @@ namespace SabreTools.Serialization.Readers
|
||||
obj.DirectoryRecordLength = data.ReadByteValue();
|
||||
obj.ExtendedAttributeRecordLength = data.ReadByteValue();
|
||||
obj.ExtentLocation = data.ReadInt32BothEndian();
|
||||
obj.ExtentLength = data.ReadInt32BothEndian();
|
||||
obj.ExtentLength = data.ReadUInt32BothEndian();
|
||||
|
||||
obj.RecordingDateTime = ParseDirectoryRecordDateTime(data);
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace SabreTools.Serialization.Wrappers
|
||||
/// <summary>
|
||||
/// List of extracted files by their sector offset
|
||||
/// </summary>
|
||||
private readonly Dictionary<int, int> extractedFiles = [];
|
||||
private readonly Dictionary<int, uint> extractedFiles = [];
|
||||
|
||||
/// <summary>
|
||||
/// List of multi-extent files written, by their FileIdentifier
|
||||
@@ -188,21 +188,21 @@ namespace SabreTools.Serialization.Wrappers
|
||||
if (!multiExtent && (File.Exists(filepath) || Directory.Exists(filepath)))
|
||||
{
|
||||
// If it's the last extent of a multi-extent file, continue to append
|
||||
if (multiExtentFiles.Exists(item => item.EqualsExactly(dr.FileIdentifier)))
|
||||
if (!multiExtentFiles.Exists(item => item.EqualsExactly(dr.FileIdentifier)))
|
||||
{
|
||||
if (includeDebug) Console.WriteLine($"File/Folder already exists, cannot extract: {filename}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
const int chunkSize = 2048 * 1024;
|
||||
const uint chunkSize = 2048 * 1024;
|
||||
lock (_dataSourceLock)
|
||||
{
|
||||
long fileOffset = ((long)dr.ExtentLocation + dr.ExtendedAttributeRecordLength) * blockLength;
|
||||
_dataSource.SeekIfPossible(fileOffset, SeekOrigin.Begin);
|
||||
|
||||
// Get the length, and make sure it won't EOF
|
||||
int length = dr.ExtentLength;
|
||||
uint length = dr.ExtentLength;
|
||||
if (length > _dataSource.Length - _dataSource.Position)
|
||||
return false;
|
||||
|
||||
@@ -211,13 +211,13 @@ namespace SabreTools.Serialization.Wrappers
|
||||
using var fs = File.Open(filepath, FileMode.Append, FileAccess.Write, FileShare.ReadWrite);
|
||||
while (length > 0)
|
||||
{
|
||||
int bytesToRead = Math.Min(length, chunkSize);
|
||||
int bytesToRead = (int)Math.Min(length, chunkSize);
|
||||
|
||||
byte[] buffer = _dataSource.ReadBytes(bytesToRead);
|
||||
fs.Write(buffer, 0, bytesToRead);
|
||||
fs.Flush();
|
||||
|
||||
length -= bytesToRead;
|
||||
length -= (uint)bytesToRead;
|
||||
}
|
||||
|
||||
// Mark the file as extracted
|
||||
|
||||
Reference in New Issue
Block a user