Skip to content

Commit 59eddb7

Browse files
authored
Fix ISO9660 extraction of large files (#46)
* ExtentLength is uint * Fix * fix2 * fix3 * fix4 * Invert multi extent final extent logic
1 parent 1096232 commit 59eddb7

File tree

3 files changed

+12
-12
lines changed

3 files changed

+12
-12
lines changed

SabreTools.Serialization/Models/ISO9660/DirectoryRecord.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ public sealed class DirectoryRecord
2828
/// <summary>
2929
/// Number of bytes allocated to this extent (not including extended attribute record length)
3030
/// </summary>
31-
public BothInt32 ExtentLength { get; set; } = 0;
31+
public BothUInt32 ExtentLength { get; set; } = 0;
3232

3333
/// <summary>
3434
/// Datetime of recording for the Directory Record

SabreTools.Serialization/Readers/ISO9660.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -635,7 +635,7 @@ public static List<PathTableGroup> ParsePathTableGroup(Stream data, short sector
635635

636636
// Use provided extent endinanness
637637
int extentLocation = bigEndian ? dr.ExtentLocation.BigEndian : dr.ExtentLocation.LittleEndian;
638-
int extentLength = bigEndian ? dr.ExtentLength.BigEndian : dr.ExtentLength.LittleEndian;
638+
uint extentLength = bigEndian ? dr.ExtentLength.BigEndian : dr.ExtentLength.LittleEndian;
639639
long extentOffset = (long)extentLocation * (long)blockLength;
640640
long extentFinal = extentOffset + (long)extentLength;
641641

@@ -668,7 +668,7 @@ public static List<PathTableGroup> ParsePathTableGroup(Stream data, short sector
668668

669669
// Read all directory records in this directory
670670
var records = new List<DirectoryRecord>();
671-
int pos = 0;
671+
uint pos = 0;
672672
while (pos < extentLength)
673673
{
674674
// Peek next byte to check whether the next record length is not greater than the end of the dir extent
@@ -677,8 +677,8 @@ public static List<PathTableGroup> ParsePathTableGroup(Stream data, short sector
677677
// If record length of 0x00, next record begins in next sector
678678
if (recordLength == 0)
679679
{
680-
int paddingLength = sectorLength - (pos % sectorLength);
681-
pos += paddingLength;
680+
int paddingLength = (int)((uint)sectorLength - (pos % (uint)sectorLength));
681+
pos += (uint)paddingLength;
682682
_ = data.ReadBytes(paddingLength);
683683

684684
// Finish parsing records if end reached
@@ -786,7 +786,7 @@ public static DirectoryRecord ParseDirectoryRecord(Stream data, bool root)
786786
obj.DirectoryRecordLength = data.ReadByteValue();
787787
obj.ExtendedAttributeRecordLength = data.ReadByteValue();
788788
obj.ExtentLocation = data.ReadInt32BothEndian();
789-
obj.ExtentLength = data.ReadInt32BothEndian();
789+
obj.ExtentLength = data.ReadUInt32BothEndian();
790790

791791
obj.RecordingDateTime = ParseDirectoryRecordDateTime(data);
792792

SabreTools.Serialization/Wrappers/ISO9660.Extraction.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ public partial class ISO9660 : IExtractable
1515
/// <summary>
1616
/// List of extracted files by their sector offset
1717
/// </summary>
18-
private readonly Dictionary<int, int> extractedFiles = [];
18+
private readonly Dictionary<int, uint> extractedFiles = [];
1919

2020
/// <summary>
2121
/// List of multi-extent files written, by their FileIdentifier
@@ -188,21 +188,21 @@ private bool ExtractFile(DirectoryRecord dr, Encoding encoding, int blockLength,
188188
if (!multiExtent && (File.Exists(filepath) || Directory.Exists(filepath)))
189189
{
190190
// If it's the last extent of a multi-extent file, continue to append
191-
if (multiExtentFiles.Exists(item => item.EqualsExactly(dr.FileIdentifier)))
191+
if (!multiExtentFiles.Exists(item => item.EqualsExactly(dr.FileIdentifier)))
192192
{
193193
if (includeDebug) Console.WriteLine($"File/Folder already exists, cannot extract: {filename}");
194194
return false;
195195
}
196196
}
197197

198-
const int chunkSize = 2048 * 1024;
198+
const uint chunkSize = 2048 * 1024;
199199
lock (_dataSourceLock)
200200
{
201201
long fileOffset = ((long)dr.ExtentLocation + dr.ExtendedAttributeRecordLength) * blockLength;
202202
_dataSource.SeekIfPossible(fileOffset, SeekOrigin.Begin);
203203

204204
// Get the length, and make sure it won't EOF
205-
int length = dr.ExtentLength;
205+
uint length = dr.ExtentLength;
206206
if (length > _dataSource.Length - _dataSource.Position)
207207
return false;
208208

@@ -211,13 +211,13 @@ private bool ExtractFile(DirectoryRecord dr, Encoding encoding, int blockLength,
211211
using var fs = File.Open(filepath, FileMode.Append, FileAccess.Write, FileShare.ReadWrite);
212212
while (length > 0)
213213
{
214-
int bytesToRead = Math.Min(length, chunkSize);
214+
int bytesToRead = (int)Math.Min(length, chunkSize);
215215

216216
byte[] buffer = _dataSource.ReadBytes(bytesToRead);
217217
fs.Write(buffer, 0, bytesToRead);
218218
fs.Flush();
219219

220-
length -= bytesToRead;
220+
length -= (uint)bytesToRead;
221221
}
222222

223223
// Mark the file as extracted

0 commit comments

Comments
 (0)