From 2f10f92500d703387535b4b51794602573e94340 Mon Sep 17 00:00:00 2001 From: Natalia Portillo Date: Wed, 31 Jul 2019 04:33:31 +0100 Subject: [PATCH] Fix ISO9660 extended attributes. --- DiscImageChef.Filesystems/ISO9660/Dir.cs | 9 ++++--- DiscImageChef.Filesystems/ISO9660/File.cs | 19 +++++++------- .../ISO9660/Structs/Internal.cs | 1 + DiscImageChef.Filesystems/ISO9660/Xattr.cs | 26 ++++++++++++++----- 4 files changed, 37 insertions(+), 18 deletions(-) diff --git a/DiscImageChef.Filesystems/ISO9660/Dir.cs b/DiscImageChef.Filesystems/ISO9660/Dir.cs index c29f80b66..afa98dbe4 100644 --- a/DiscImageChef.Filesystems/ISO9660/Dir.cs +++ b/DiscImageChef.Filesystems/ISO9660/Dir.cs @@ -148,7 +148,8 @@ namespace DiscImageChef.Filesystems.ISO9660 Interleave = record.interleave, VolumeSequenceNumber = record.volume_sequence_number, Filename = Encoding.GetString(data, entryOff + DirectoryRecordSize, record.name_len), - Timestamp = DecodeHighSierraDateTime(record.date) + Timestamp = DecodeHighSierraDateTime(record.date), + XattrLength = record.xattr_len }; if(entry.Flags.HasFlag(FileFlags.Directory) && usePathTable) @@ -201,7 +202,8 @@ namespace DiscImageChef.Filesystems.ISO9660 FileUnitSize = record.file_unit_size, Interleave = record.interleave, VolumeSequenceNumber = record.volume_sequence_number, - Timestamp = DecodeIsoDateTime(record.date) + Timestamp = DecodeIsoDateTime(record.date), + XattrLength = record.xattr_len }; if(entry.Flags.HasFlag(FileFlags.Directory) && usePathTable) @@ -256,7 +258,8 @@ namespace DiscImageChef.Filesystems.ISO9660 Interleave = 0, VolumeSequenceNumber = record.volume_sequence_number, Filename = entry.Filename, - Timestamp = DecodeIsoDateTime(record.date) + Timestamp = DecodeIsoDateTime(record.date), + XattrLength = 0 }; if(hasResourceFork) entries[entry.Filename].ResourceFork = entry; diff --git a/DiscImageChef.Filesystems/ISO9660/File.cs b/DiscImageChef.Filesystems/ISO9660/File.cs index 0e29ca7bf..222f45be4 100644 --- a/DiscImageChef.Filesystems/ISO9660/File.cs +++ b/DiscImageChef.Filesystems/ISO9660/File.cs @@ -51,15 +51,17 @@ namespace DiscImageChef.Filesystems.ISO9660 if(entry.Flags.HasFlag(FileFlags.Directory) && !debug) return Errno.IsDirectory; - if(entry.Size == 0) + if(entry.Size - entry.XattrLength == 0) { buf = new byte[0]; return Errno.NoError; } - if(offset >= entry.Size) return Errno.InvalidArgument; + if(offset >= entry.Size - entry.XattrLength) return Errno.InvalidArgument; - if(size + offset >= entry.Size) size = entry.Size - offset; + if(size + offset + entry.XattrLength >= entry.Size) size = entry.Size - offset - entry.XattrLength; + + offset += entry.XattrLength; // TODO: XA long firstSector = offset / 2048; @@ -89,7 +91,7 @@ namespace DiscImageChef.Filesystems.ISO9660 Attributes = new FileAttributes(), Blocks = entry.Size / 2048, // TODO: XA BlockSize = 2048, - Length = entry.Size, + Length = entry.Size - entry.XattrLength, Inode = entry.Extent, Links = 1, LastWriteTimeUtc = entry.Timestamp @@ -198,14 +200,13 @@ namespace DiscImageChef.Filesystems.ISO9660 if(entry.SymbolicLink != null) stat.Attributes |= FileAttributes.Symlink; - if(entry.AssociatedFile is null || entry.AssociatedFile.Extent == 0 || entry.AssociatedFile.Size == 0) - return Errno.NoError; + if(entry.XattrLength == 0) return Errno.NoError; // TODO: XA - uint eaSizeInSectors = entry.AssociatedFile.Size / 2048; - if(entry.AssociatedFile.Size % 2048 > 0) eaSizeInSectors++; + uint eaSizeInSectors = (uint)(entry.XattrLength / 2048); + if(entry.XattrLength % 2048 > 0) eaSizeInSectors++; - byte[] ea = image.ReadSectors(entry.AssociatedFile.Extent, eaSizeInSectors); + byte[] ea = image.ReadSectors(entry.Extent, eaSizeInSectors); ExtendedAttributeRecord ear = Marshal.ByteArrayToStructureLittleEndian(ea); diff --git a/DiscImageChef.Filesystems/ISO9660/Structs/Internal.cs b/DiscImageChef.Filesystems/ISO9660/Structs/Internal.cs index 68a26c988..add4a358c 100644 --- a/DiscImageChef.Filesystems/ISO9660/Structs/Internal.cs +++ b/DiscImageChef.Filesystems/ISO9660/Structs/Internal.cs @@ -87,6 +87,7 @@ namespace DiscImageChef.Filesystems.ISO9660 public DateTime? Timestamp; public ushort VolumeSequenceNumber; public CdromXa? XA; + public byte XattrLength; public override string ToString() => Filename; } diff --git a/DiscImageChef.Filesystems/ISO9660/Xattr.cs b/DiscImageChef.Filesystems/ISO9660/Xattr.cs index 39e0644d1..a20489695 100644 --- a/DiscImageChef.Filesystems/ISO9660/Xattr.cs +++ b/DiscImageChef.Filesystems/ISO9660/Xattr.cs @@ -16,13 +16,14 @@ namespace DiscImageChef.Filesystems.ISO9660 xattrs = new List(); - if(entry.AssociatedFile != null) xattrs.Add("org.iso.9660.ea"); + if(entry.XattrLength > 0) xattrs.Add("org.iso.9660.ea"); + if(entry.AssociatedFile != null) xattrs.Add("org.iso.9660.AssociatedFile"); if(entry.AppleDosType != null) xattrs.Add("com.apple.dos.type"); if(entry.AppleProDosType != null) xattrs.Add("com.apple.prodos.type"); if(entry.ResourceFork != null) xattrs.Add("com.apple.ResourceFork"); if(entry.FinderInfo != null) xattrs.Add("com.apple.FinderInfo"); if(entry.AppleIcon != null) xattrs.Add("com.apple.Macintosh.Icon"); - if(entry.AmigaComment != null) xattrs.Add("com.amiga.comments"); + if(entry.AmigaComment != null) xattrs.Add("com.amiga.comments"); return Errno.NoError; } @@ -38,6 +39,19 @@ namespace DiscImageChef.Filesystems.ISO9660 switch(xattr) { case "org.iso.9660.ea": + if(entry.XattrLength == 0) return Errno.NoSuchExtendedAttribute; + + // TODO: XA + uint eaSizeInSectors = (uint)(entry.XattrLength / 2048); + if(entry.XattrLength % 2048 > 0) eaSizeInSectors++; + + byte[] ea = image.ReadSectors(entry.Extent, eaSizeInSectors); + + buf = new byte[entry.AssociatedFile.Size]; + Array.Copy(ea, 0, buf, 0, buf.LongLength); + + return Errno.NoError; + case "org.iso.9660.AssociatedFile": if(entry.AssociatedFile is null) return Errno.NoSuchExtendedAttribute; if(entry.AssociatedFile.Extent == 0) return Errno.InvalidArgument; @@ -49,13 +63,13 @@ namespace DiscImageChef.Filesystems.ISO9660 } // TODO: XA - uint eaSizeInSectors = entry.AssociatedFile.Size / 2048; - if(entry.AssociatedFile.Size % 2048 > 0) eaSizeInSectors++; + uint associatedFileSize = entry.AssociatedFile.Size / 2048; + if(entry.AssociatedFile.Size % 2048 > 0) associatedFileSize++; - byte[] ea = image.ReadSectors(entry.AssociatedFile.Extent, eaSizeInSectors); + byte[] associatedFile = image.ReadSectors(entry.AssociatedFile.Extent, associatedFileSize); buf = new byte[entry.AssociatedFile.Size]; - Array.Copy(ea, 0, buf, 0, buf.LongLength); + Array.Copy(associatedFile, 0, buf, 0, buf.LongLength); return Errno.NoError; case "com.apple.dos.type":