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:
Deterous
2025-12-02 21:31:31 +09:00
committed by GitHub
parent 1096232f9d
commit 59eddb7129
3 changed files with 12 additions and 12 deletions

View File

@@ -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

View File

@@ -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);

View File

@@ -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