in Agents/Xamarin.Interactive/Collections/PropertyList.cs [340:403]
void ValidateTrailer ()
{
// Don't overflow on number of objects or offset of the table
if (trailer.NumObjects >= Int64.MaxValue)
Fatal ("trailer.NumObjects >= Int64.MaxValue");
else if (trailer.OffsetTableOffset >= Int64.MaxValue)
Fatal ("trailer.OffsetTableOffset >= Int64.MaxValue)");
// Must be a minimum of one object
if (trailer.NumObjects < 1)
Fatal ("trailer.NumObjects < 1");
// Ensure the top object is in range
if (trailer.NumObjects <= trailer.TopObject)
Fatal ("trailer.NumObjects <= trailer.TopObject");
// The offset table must be at least 9 bytes into the file
// ('bplist??' + 1 byte of object table data)
if (trailer.OffsetTableOffset < 9)
Fatal ("trailer.OffsetTableOffset < 9");
// The trailer must point to a value before itself in the file
if ((uint)(stream.Length - TRAILER_SIZE) <= trailer.OffsetTableOffset)
Fatal ("stream.Length - TRAILER_SIZE <= trailer.OffsetTableOffset");
// Minimum of 1 byte for the size of integers and refs in the file
if (trailer.OffsetIntSize < 1)
Fatal ("trailer.OffsetIntSize < 1");
else if (trailer.ObjectRefSize < 1)
Fatal ("trailer.ObjectRefSize < 1");
// Total size of offset table must not overflow
var offsetTableSize = checked (trailer.NumObjects * trailer.OffsetIntSize);
// Offset table must have at least one entry
if (offsetTableSize < 1)
Fatal ("trailer offsetTableSize < 1");
// Ensure the size of the offset table and data sections do not overflow
var objectDataSize = trailer.OffsetTableOffset - 8;
var tmp = checked (objectDataSize + 8);
tmp = checked (tmp + offsetTableSize);
tmp = checked (tmp + TRAILER_SIZE);
// The total size of the file should be equal to offsetTableOffset + TRAILER_SIZE
if ((ulong)stream.Length != tmp)
Fatal ("stream.Length != trailer.OffsetTableOffset + TRAILER_SIZE");
// The object refs must be the right size to point into the offset table.
// That is, if the count of objects is 260, but only 1 byte is used to
// store references (max value 255), something is wrong.
if (trailer.ObjectRefSize < 8 && (1UL << (8 * trailer.ObjectRefSize)) <= trailer.NumObjects)
Fatal ("trailer.ObjectRefSize invalid");
// The integers used for pointers in the offset table must be able to
// reach as far as the start of the offset table.
if (trailer.OffsetIntSize < 8 && (1UL << (8 * trailer.OffsetIntSize)) <= trailer.OffsetTableOffset)
Fatal ("trailer.OffsetIntSize invalid");
Seek (trailer.OffsetTableOffset + trailer.TopObject * trailer.OffsetIntSize);
var ofs = ReadSizedInt (trailer.OffsetIntSize);
if (ofs < 8 || trailer.OffsetTableOffset <= ofs)
Fatal ("offset ({0}) < 8 || trailer.OffsetTableOffset <= offset ({0})", ofs);
}