Skip to content

Commit

Permalink
MachReader.Read: Don't use an iterator
Browse files Browse the repository at this point in the history
MachReader.Read will read the header of the a fat mach object, and will create a MachObjectFile for each mach object in the fat mach object.

It currently does so in an iterator.  This reads a MachFatObject, yields control to the caller, and then reads the next MachFatObject.  However, the method does assume that the state of `stream` does not change.  That's not guaranteed to be the case -- a caller could write code like this:

```csharp
foreach(var mach in Read(stream))
{
    // Read data from the mach object, which will
    // alter the state of `stream`
}
```

To avoid this, change `MachReader.Read` to enumerate all architectures, create `MachObjectFile` objects, and only then yield control to the caller.
  • Loading branch information
qmfrederik committed Nov 27, 2022
1 parent ce0f5e9 commit 9be739d
Showing 1 changed file with 7 additions and 3 deletions.
10 changes: 7 additions & 3 deletions Melanzana.MachO/MachReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -415,11 +415,13 @@ public static bool IsFatMach(Stream stream)
return magic == MachMagic.FatMagicLittleEndian || magic == MachMagic.FatMagicBigEndian;
}

public static IEnumerable<MachObjectFile> Read(Stream stream)
public static IList<MachObjectFile> Read(Stream stream)
{
var magic = ReadMagic(stream);
var magicBuffer = new byte[4];

List<MachObjectFile> values = new List<MachObjectFile>();

if (magic == MachMagic.FatMagicLittleEndian || magic == MachMagic.FatMagicBigEndian)
{
var headerBuffer = new byte[Math.Max(FatHeader.BinarySize, FatArchHeader.BinarySize)];
Expand All @@ -433,13 +435,15 @@ public static IEnumerable<MachObjectFile> Read(Stream stream)
var machOSlice = stream.Slice(fatArchHeader.Offset, fatArchHeader.Size);
machOSlice.ReadFully(magicBuffer);
magic = (MachMagic)BinaryPrimitives.ReadUInt32BigEndian(magicBuffer);
yield return ReadSingle(fatArchHeader, magic, machOSlice);
values.Add(ReadSingle(fatArchHeader, magic, machOSlice));
}
}
else
{
yield return ReadSingle(null, magic, stream);
values.Add(ReadSingle(null, magic, stream));
}

return values;
}
}
}

0 comments on commit 9be739d

Please sign in to comment.