-
Notifications
You must be signed in to change notification settings - Fork 17.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
image/png: Add options to tolerate invalid checksums in ancillary chunks #43382
Comments
/cc @nigeltao |
http://www.libpng.org/pub/png/spec/1.2/PNG-Structure.html says:
I've updated the issue description to reflect that we can ignore ancillary chunks (i.e. those that start with a lowercase letter). The following patch works around the problem: diff --git a/src/image/png/reader.go b/src/image/png/reader.go
index 910520bd4b..734bf4757b 100644
--- a/src/image/png/reader.go
b/src/image/png/reader.go
@@ -926,6 926,13 @@ func (d *decoder) parseChunk() error {
d.crc.Write(ignored[:n])
length -= uint32(n)
}
// If this is an ancillary chunk, we can ignore the checksum since it's not required
if d.tmp[4] >> 5 & 0x1 == 1 {
d.verifyChecksum()
return nil
}
return d.verifyChecksum()
} |
Ancilliary chunks can be ignored, but still, an invalid checksum means that it's an invalid PNG file. And if you're going to ignore some checksums (as per "be liberal in what you accept"), it'd arguably be simpler to just ignore all checksums. And while that's possible (and a supporting argument is that the attached file does seem to render in the Chrome web browser), I'd like to hold the line against "be liberal in what you accept" as much as possible. Part of the problem (with PNG but also with file formats generally) is that different implementations have decided to "be liberal in what you accept" in different, incompatible, undocumented and possibly insecure ways. FWIW, the spec does not say "ancilliary" in this bullet point (despite discussing ancilliary and critical chunks in sibling bullet points):
Regarding the "add an option" part, that's easier said than done. It's an API design failure dating back to Go 1.0, but the For the immediate itch, where this (invalid) PNG file is being rejected, the |
Thanks for the feedback. This is a good point.
Yeah, I realize that it's an involved issue.
Thanks. According to our logs, we see a lot of user-uploaded avatars with PNG decoding errors, usually with an invalid iCCP profile with a bad checksum. I'm not quite sure why this is happening in the first place. My colleague implemented such a wrapper in https://gitlab.com/gitlab-org/gitlab-workhorse/-/merge_requests/673/diffs. It's a little tricky to get right. |
We did some analysis and found that all corrupted iCCP chunks were all saved by GIMP 2.10.x, which is the latest stable version. We suspect these issues are related: |
I have since learned that libpng, by default, treats invalid checksums as an error for critical chunks but a warning for ancillary chunks. In practice, invalid ancillary checksums are ignored. https://github.com/glennrp/libpng/blob/dbe3e0c43e549a1602286144d94b0666549b18e6/png.h#L1436 I'd be open to Go's |
Here's my implementation: Feel free to copy/paste it. |
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
Yes.
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
Decoding the attached image that has valid data checksums but an invalid ICCP checksum fails a decode entirely.
Most image programs ignore the invalid ICC profile, but calling
image.Decode
fails to load this image:pngcheck
confirms there is an invalid checksum in the iCCP chunk:Since the ICC profile isn't absolutely necessary to render a PNG, we ought to be able to detect this error but not fail outright.
This is similar to #10447 and relates to #27830.
What did you expect to see?
The image decoded but the ICC profile skipped.
What did you see instead?
A hard failure.
The text was updated successfully, but these errors were encountered: