mirror of
https://github.com/aaru-dps/Aaru.git
synced 2025-12-16 19:24:25 +00:00
In ISO9660 filesystem pass thru error reading extents. Fixes #652
This commit is contained in:
@@ -164,7 +164,10 @@ public sealed partial class ISO9660
|
||||
Dictionary<string, DecodedDirectoryEntry> entries = new();
|
||||
var entryOff = 0;
|
||||
|
||||
byte[] data = ReadSingleExtent(size, (uint)start);
|
||||
ErrorNumber errno = ReadSingleExtent(size, (uint)start, out byte[] data);
|
||||
|
||||
if(errno != ErrorNumber.NoError)
|
||||
return entries;
|
||||
|
||||
while(entryOff + _cdiDirectoryRecordSize < data.Length)
|
||||
{
|
||||
@@ -241,7 +244,10 @@ public sealed partial class ISO9660
|
||||
Dictionary<string, DecodedDirectoryEntry> entries = new();
|
||||
var entryOff = 0;
|
||||
|
||||
byte[] data = ReadSingleExtent(size, (uint)start);
|
||||
ErrorNumber errno = ReadSingleExtent(size, (uint)start, out byte[] data);
|
||||
|
||||
if(errno != ErrorNumber.NoError)
|
||||
return entries;
|
||||
|
||||
while(entryOff + _directoryRecordSize < data.Length)
|
||||
{
|
||||
@@ -312,7 +318,10 @@ public sealed partial class ISO9660
|
||||
Dictionary<string, DecodedDirectoryEntry> entries = new();
|
||||
var entryOff = 0;
|
||||
|
||||
byte[] data = ReadSingleExtent(size, (uint)start);
|
||||
ErrorNumber errno = ReadSingleExtent(size, (uint)start, out byte[] data);
|
||||
|
||||
if(errno != ErrorNumber.NoError)
|
||||
return entries;
|
||||
|
||||
while(entryOff + _directoryRecordSize < data.Length)
|
||||
{
|
||||
@@ -477,10 +486,13 @@ public sealed partial class ISO9660
|
||||
if(transTblEntry.Value == null)
|
||||
return;
|
||||
|
||||
byte[] transTbl = ReadWithExtents(0, (long)transTblEntry.Value.Size, transTblEntry.Value.Extents,
|
||||
transTblEntry.Value.XA?.signature == XA_MAGIC &&
|
||||
transTblEntry.Value.XA?.attributes.HasFlag(XaAttributes.Interleaved) == true,
|
||||
transTblEntry.Value.XA?.filenumber ?? 0);
|
||||
ErrorNumber errno = ReadWithExtents(0, (long)transTblEntry.Value.Size, transTblEntry.Value.Extents,
|
||||
transTblEntry.Value.XA?.signature == XA_MAGIC &&
|
||||
transTblEntry.Value.XA?.attributes.HasFlag(XaAttributes.Interleaved) ==
|
||||
true, transTblEntry.Value.XA?.filenumber ?? 0, out byte[] transTbl);
|
||||
|
||||
if(errno != ErrorNumber.NoError)
|
||||
return;
|
||||
|
||||
var mr = new MemoryStream(transTbl, 0, (int)transTblEntry.Value.Size, false);
|
||||
var sr = new StreamReader(mr, Encoding);
|
||||
@@ -957,9 +969,10 @@ public sealed partial class ISO9660
|
||||
Marshal.ByteArrayToStructureLittleEndian<ContinuationArea>(data, systemAreaOff,
|
||||
Marshal.SizeOf<ContinuationArea>());
|
||||
|
||||
byte[] caData = ReadSingleExtent(ca.offset, ca.ca_length, ca.block);
|
||||
errno = ReadSingleExtent(ca.offset, ca.ca_length, ca.block, out byte[] caData);
|
||||
|
||||
DecodeSystemArea(caData, 0, (int)ca.ca_length, ref entry, out hasResourceFork);
|
||||
if(errno == ErrorNumber.NoError)
|
||||
DecodeSystemArea(caData, 0, (int)ca.ca_length, ref entry, out hasResourceFork);
|
||||
|
||||
systemAreaOff += ceLength;
|
||||
|
||||
|
||||
@@ -157,12 +157,10 @@ public sealed partial class ISO9660
|
||||
return ErrorNumber.UnexpectedException;
|
||||
}
|
||||
|
||||
buf = ReadWithExtents(offset, size, entry.Extents,
|
||||
entry.XA?.signature == XA_MAGIC &&
|
||||
entry.XA?.attributes.HasFlag(XaAttributes.Interleaved) == true,
|
||||
entry.XA?.filenumber ?? 0);
|
||||
|
||||
return ErrorNumber.NoError;
|
||||
return ReadWithExtents(offset, size, entry.Extents,
|
||||
entry.XA?.signature == XA_MAGIC &&
|
||||
entry.XA?.attributes.HasFlag(XaAttributes.Interleaved) == true,
|
||||
entry.XA?.filenumber ?? 0, out buf);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -384,7 +382,10 @@ public sealed partial class ISO9660
|
||||
stat.Mode |= 256;
|
||||
}
|
||||
|
||||
byte[] ea = ReadSingleExtent(entry.XattrLength * _blockSize, entry.Extents[0].extent);
|
||||
ErrorNumber errno = ReadSingleExtent(entry.XattrLength * _blockSize, entry.Extents[0].extent, out byte[] ea);
|
||||
|
||||
if(errno != ErrorNumber.NoError)
|
||||
return ErrorNumber.NoError;
|
||||
|
||||
ExtendedAttributeRecord ear = Marshal.ByteArrayToStructureLittleEndian<ExtendedAttributeRecord>(ea);
|
||||
|
||||
@@ -491,22 +492,23 @@ public sealed partial class ISO9660
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
byte[] ReadSingleExtent(long size, uint startingSector, bool interleaved = false, byte fileNumber = 0) =>
|
||||
ReadWithExtents(0, size, new List<(uint extent, uint size)>
|
||||
{
|
||||
(startingSector, (uint)size)
|
||||
}, interleaved, fileNumber);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
byte[] ReadSingleExtent(long offset, long size, uint startingSector, bool interleaved = false,
|
||||
byte fileNumber = 0) => ReadWithExtents(offset, size, new List<(uint extent, uint size)>
|
||||
ErrorNumber ReadSingleExtent(long size, uint startingSector, out byte[] buffer, bool interleaved = false,
|
||||
byte fileNumber = 0) => ReadWithExtents(0, size, new List<(uint extent, uint size)>
|
||||
{
|
||||
(startingSector, (uint)size)
|
||||
}, interleaved, fileNumber);
|
||||
}, interleaved, fileNumber, out buffer);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
ErrorNumber ReadSingleExtent(long offset, long size, uint startingSector, out byte[] buffer,
|
||||
bool interleaved = false, byte fileNumber = 0) => ReadWithExtents(offset, size,
|
||||
new List<(uint extent, uint size)>
|
||||
{
|
||||
(startingSector, (uint)size)
|
||||
}, interleaved, fileNumber, out buffer);
|
||||
|
||||
// Cannot think how to make this faster, as we don't know the mode sector until it is read, but we have size in bytes
|
||||
byte[] ReadWithExtents(long offset, long size, List<(uint extent, uint size)> extents, bool interleaved,
|
||||
byte fileNumber)
|
||||
ErrorNumber ReadWithExtents(long offset, long size, List<(uint extent, uint size)> extents, bool interleaved,
|
||||
byte fileNumber, out byte[] buffer)
|
||||
{
|
||||
var ms = new MemoryStream();
|
||||
long currentFilePos = 0;
|
||||
@@ -528,10 +530,18 @@ public sealed partial class ISO9660
|
||||
ErrorNumber errno = ReadSector(extents[i].extent + currentExtentSector, out byte[] sector, interleaved,
|
||||
fileNumber);
|
||||
|
||||
if(errno != ErrorNumber.NoError ||
|
||||
sector is null)
|
||||
if(errno != ErrorNumber.NoError)
|
||||
{
|
||||
buffer = ms.ToArray();
|
||||
|
||||
return errno;
|
||||
}
|
||||
|
||||
if(sector is null)
|
||||
{
|
||||
currentExtentSector++;
|
||||
leftExtentSize -= 2048;
|
||||
currentFilePos += 2048;
|
||||
|
||||
continue;
|
||||
}
|
||||
@@ -565,7 +575,9 @@ public sealed partial class ISO9660
|
||||
if(ms.Length >= size)
|
||||
ms.SetLength(size);
|
||||
|
||||
return ms.ToArray();
|
||||
buffer = ms.ToArray();
|
||||
|
||||
return ErrorNumber.NoError;
|
||||
}
|
||||
|
||||
byte[] ReadSubheaderWithExtents(List<(uint extent, uint size)> extents, bool copy)
|
||||
|
||||
@@ -288,8 +288,11 @@ public sealed partial class ISO9660
|
||||
{
|
||||
_blockSize = hsvd.Value.logical_block_size;
|
||||
|
||||
pathTableData = ReadSingleExtent(hsvd.Value.path_table_size,
|
||||
Swapping.Swap(hsvd.Value.mandatory_path_table_msb));
|
||||
errno = ReadSingleExtent(hsvd.Value.path_table_size, Swapping.Swap(hsvd.Value.mandatory_path_table_msb),
|
||||
out pathTableData);
|
||||
|
||||
if(errno != ErrorNumber.NoError)
|
||||
pathTableData = null;
|
||||
|
||||
fsFormat = "High Sierra Format";
|
||||
|
||||
@@ -300,7 +303,10 @@ public sealed partial class ISO9660
|
||||
{
|
||||
_blockSize = fsvd.Value.logical_block_size;
|
||||
|
||||
pathTableData = ReadSingleExtent(fsvd.Value.path_table_size, fsvd.Value.path_table_addr);
|
||||
errno = ReadSingleExtent(fsvd.Value.path_table_size, fsvd.Value.path_table_addr, out pathTableData);
|
||||
|
||||
if(errno != ErrorNumber.NoError)
|
||||
pathTableData = null;
|
||||
|
||||
fsFormat = "CD-i";
|
||||
|
||||
@@ -313,7 +319,11 @@ public sealed partial class ISO9660
|
||||
{
|
||||
_blockSize = pvd.Value.logical_block_size;
|
||||
|
||||
pathTableData = ReadSingleExtent(pvd.Value.path_table_size, Swapping.Swap(pvd.Value.type_m_path_table));
|
||||
errno = ReadSingleExtent(pvd.Value.path_table_size, Swapping.Swap(pvd.Value.type_m_path_table),
|
||||
out pathTableData);
|
||||
|
||||
if(errno != ErrorNumber.NoError)
|
||||
pathTableData = null;
|
||||
|
||||
fsFormat = "ISO9660";
|
||||
|
||||
@@ -325,7 +335,7 @@ public sealed partial class ISO9660
|
||||
|
||||
if(_pathTable is null)
|
||||
{
|
||||
pathTableData = ReadSingleExtent(pathTableData.Length, pathTableLsbLocation);
|
||||
ReadSingleExtent(pathTableData.Length, pathTableLsbLocation, out pathTableData);
|
||||
|
||||
_pathTable = _highSierra ? DecodeHighSierraPathTable(pathTableData) : DecodePathTable(pathTableData);
|
||||
}
|
||||
@@ -472,7 +482,7 @@ public sealed partial class ISO9660
|
||||
|
||||
try
|
||||
{
|
||||
_ = ReadSingleExtent(rootSize, rootLocation);
|
||||
ReadSingleExtent(rootSize, rootLocation, out byte[] _);
|
||||
}
|
||||
catch
|
||||
{
|
||||
@@ -748,12 +758,10 @@ public sealed partial class ISO9660
|
||||
|
||||
_statfs = new FileSystemInfo
|
||||
{
|
||||
Blocks = decodedVd.Blocks,
|
||||
FilenameLength = (ushort)(jolietvd != null ? _namespace == Namespace.Joliet
|
||||
? 110
|
||||
: 255 : 255),
|
||||
PluginId = Id,
|
||||
Type = fsFormat
|
||||
Blocks = decodedVd.Blocks,
|
||||
FilenameLength = (ushort)(jolietvd != null ? _namespace == Namespace.Joliet ? 110 : 255 : 255),
|
||||
PluginId = Id,
|
||||
Type = fsFormat
|
||||
};
|
||||
|
||||
_directoryCache = new Dictionary<string, Dictionary<string, DecodedDirectoryEntry>>();
|
||||
|
||||
@@ -114,15 +114,12 @@ public sealed partial class ISO9660
|
||||
switch(xattr)
|
||||
{
|
||||
case "org.iso.9660.ea":
|
||||
if(entry.XattrLength == 0)
|
||||
return ErrorNumber.NoSuchExtendedAttribute;
|
||||
return entry.XattrLength == 0
|
||||
? ErrorNumber.NoSuchExtendedAttribute
|
||||
: entry.Extents is null
|
||||
? ErrorNumber.InvalidArgument
|
||||
: ReadSingleExtent(entry.XattrLength * _blockSize, entry.Extents[0].extent, out buf);
|
||||
|
||||
if(entry.Extents is null)
|
||||
return ErrorNumber.InvalidArgument;
|
||||
|
||||
buf = ReadSingleExtent(entry.XattrLength * _blockSize, entry.Extents[0].extent);
|
||||
|
||||
return ErrorNumber.NoError;
|
||||
case "org.iso.9660.AssociatedFile":
|
||||
if(entry.AssociatedFile is null)
|
||||
return ErrorNumber.NoSuchExtendedAttribute;
|
||||
@@ -137,12 +134,10 @@ public sealed partial class ISO9660
|
||||
return ErrorNumber.NoError;
|
||||
}
|
||||
|
||||
buf = ReadWithExtents(0, (long)entry.AssociatedFile.Size, entry.AssociatedFile.Extents,
|
||||
entry.AssociatedFile.XA?.signature == XA_MAGIC &&
|
||||
entry.AssociatedFile.XA?.attributes.HasFlag(XaAttributes.Interleaved) == true,
|
||||
entry.AssociatedFile.XA?.filenumber ?? 0);
|
||||
|
||||
return ErrorNumber.NoError;
|
||||
return ReadWithExtents(0, (long)entry.AssociatedFile.Size, entry.AssociatedFile.Extents,
|
||||
entry.AssociatedFile.XA?.signature == XA_MAGIC &&
|
||||
entry.AssociatedFile.XA?.attributes.HasFlag(XaAttributes.Interleaved) == true,
|
||||
entry.AssociatedFile.XA?.filenumber ?? 0, out buf);
|
||||
case "com.apple.dos.type":
|
||||
if(entry.AppleDosType is null)
|
||||
return ErrorNumber.NoSuchExtendedAttribute;
|
||||
@@ -172,12 +167,10 @@ public sealed partial class ISO9660
|
||||
return ErrorNumber.NoError;
|
||||
}
|
||||
|
||||
buf = ReadWithExtents(0, (long)entry.ResourceFork.Size, entry.ResourceFork.Extents,
|
||||
entry.ResourceFork.XA?.signature == XA_MAGIC &&
|
||||
entry.ResourceFork.XA?.attributes.HasFlag(XaAttributes.Interleaved) == true,
|
||||
entry.ResourceFork.XA?.filenumber ?? 0);
|
||||
|
||||
return ErrorNumber.NoError;
|
||||
return ReadWithExtents(0, (long)entry.ResourceFork.Size, entry.ResourceFork.Extents,
|
||||
entry.ResourceFork.XA?.signature == XA_MAGIC &&
|
||||
entry.ResourceFork.XA?.attributes.HasFlag(XaAttributes.Interleaved) == true,
|
||||
entry.ResourceFork.XA?.filenumber ?? 0, out buf);
|
||||
case "com.apple.FinderInfo":
|
||||
if(entry.FinderInfo is null)
|
||||
return ErrorNumber.NoSuchExtendedAttribute;
|
||||
|
||||
Reference in New Issue
Block a user