3 ms·
Thank you for the correction! It has been many years since I looked into this matter, and I seem to have forgotten that detail. Digging through my sent box, t
by dalke 4y ago
Thank you for the correction!
It has been many years since I looked into this matter, and I seem to have forgotten that detail.
Digging through my sent box, to png-mng-misc, I see that knew that back in 2012!
I also wrote that most of the tools I checked didn't verify the CRC:
> I tried a PNG with an IDAT chunk with an invalid CRC on various software
on the my Mac. Unless I messed up my testing, the desktop, email preview,
OmniGraffle, and Pixen.app all used the chunk with the invalid CRC.
My thread was "I would like some insight about PNG CRC and other experience" in case someone wants to dig it up.
I was able to make an PNG with a length field which, if changed, would produce another PNG showing a different result. At least one of the PNGs had an invalid checksum, but was still displayed.
EDIT: I found a public copy of the thread at https://png-mng-misc.narkive.com/YgUoUekk/i-would-like-some-insight-about-png-crc-and-other-experience https://png-mng-misc.narkive.com/YgUoUekk/i-would-like-some-... .
- dalke 4y agoFor what it's worth, here's an example of two PNGs which differ by 1 bit, in the length. http://dalkescientific.com/xo.png http://dalkescientific.com/xo.png is a PNG for an "O" with two IDAT blocks: 'IHDR' 13 (this is the chunk data size, excluding the 4 bytes of crc) 'xtra' 0 'IDAT' 1012 <-- this one is displayed 'IDAT' 1090 <-- this one is ignored 'IEND' 0 http://dalkescientific.com/xo_bad.png http://dalkescientific.com/xo_bad.png is an invalid PNG for an "X" with one IDAT block and with an invalid checksum: 'IHDR' 13 'xtra' 1024 <-- the extra length contains what was the first IDAT 'IDAT' 1090 <-- this one is displayed 'IEND' 0 Both display in Preview.app, Firefox, and Safari. They differ only in byte offset 35, where one has a chr(0) and the other a chr(4): % python -c 'print(set(enumerate(open("xo.png", "rb").read()))\ .symmetric_difference(\ set(enumerate(open("xo_bad.png", "rb").read()))))' {(35, 0), (35, 4)} With a bit more work I could probably construct PNGs which are both valid, and which differ only by a bit. It would require brute-forcing some chunk data so the CRCs would get a match. I have some ideas on how to make it so there's only one valid (and different) IDAT block as well, but that's more than I can do in an evening.