apple-platform-rs
apple-platform-rs copied to clipboard
DMG reader doesn't emit proper byte count for Ignore and Zero chunks
Currently, the DMG reader treats all Comment
, Ignore
, and Zero
block chunks as an array of 0s of length compressed_bytes
.
When reading DMGs produced by Apple's tooling, I was seeing corrupted partition data that coincided with the reading of Ignore
and Zero
block chunks. The following patch seems to fix things:
diff --git a/apple-dmg/src/lib.rs b/apple-dmg/src/lib.rs
index 6bd5678c..e0e40085 100644
--- a/apple-dmg/src/lib.rs
+++ b/apple-dmg/src/lib.rs
@@ -82,7 +82,10 @@ impl<R: Read + Seek> DmgReader<R> {
self.r.seek(SeekFrom::Start(chunk.compressed_offset))?;
let compressed_chunk = (&mut self.r).take(chunk.compressed_length);
match chunk.ty().expect("unknown chunk type") {
- ChunkType::Ignore | ChunkType::Zero | ChunkType::Comment => {
+ ChunkType::Zero | ChunkType::Ignore => {
+ Ok(Box::new(std::io::repeat(0).take(chunk.sector_count * 512)) as Box<dyn Read>)
+ }
+ ChunkType::Comment => {
Ok(Box::new(std::io::repeat(0).take(chunk.compressed_length)) as Box<dyn Read>)
}
ChunkType::Raw => Ok(Box::new(compressed_chunk)),
However, applying this patch causes tests to fail. Specifically the only_read_dmg
test. This test attempts to create a copy of the vendored example.dmg
file and verify it roundtrips properly. The test fails because the checksums differ:
for i in 0..dmg.plist().partitions().len() {
let table = dmg.partition_table(i)?;
let data = dmg.partition_data(i)?;
let expected = u32::from(table.checksum);
let calculated = crc32fast::hash(&data);
assert_eq!(expected, calculated);
}
And the checksums differ because the code change causes the emitted partition data to change, which changes the checksum.
@dvc94ch can you provide insight on how example.dmg
was created? Was it created via Apple's tooling or this repo's Rust code? If it was produced with our Rust code, I think the checksums may be wrong. But without knowing what is supposed to be in the partition data, I can't (easily) pinpoint bugs in the DMG code.
Think it was created with apple tooling, but it's been too long...