Skip to content

fix(ico): Various validity checks and error handling for corruptions#5088

Open
lgritz wants to merge 3 commits intoAcademySoftwareFoundation:mainfrom
lgritz:lg-icofix
Open

fix(ico): Various validity checks and error handling for corruptions#5088
lgritz wants to merge 3 commits intoAcademySoftwareFoundation:mainfrom
lgritz:lg-icofix

Conversation

@lgritz
Copy link
Collaborator

@lgritz lgritz commented Mar 13, 2026

  1. Validity check the resolution/channels.

  2. Also, in png_pvt.h's read_info(), found a spot where errors were being sent to the global error reporter instead of to the PNG reader's own error store. (It is relevant to this PR because that is called by the ICO code for certain ico files that are really using PNG encoding.)

  3. Handle scanline width that's not 8 pixel multiple without running over buffer limits.

  4. Guard against possible palette array overrun for 4bpp case. The 1- and 8-bpp palette cases already had computed the palette index and checked for being in range before accessing the array. But the 4-bpp case did not!

Items 1 & 2 were entirely LG. Items 3 & 4 were identified and fixed with the assistance of Claude Code / Opus 4.6 -- it was really helpful! I'm honestly not sure if it saved me 5 hours or closer to 5 minutes, but even if short, it would not have been at all fun to trace through by hand to find a subtle case that we previously forgot to check.

Assisted-by: Claude Opus 4.6 noreply@anthropic.com

Copy link
Contributor

@jessey-git jessey-git left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are several calculations of k inside readimg() that will all have integer overflows like those on lines 341 and 430 given sufficient widths and heights.

lgritz added 3 commits March 15, 2026 14:29
1. Validity check the resolution/channels.

2. Also, in png_pvt.h's `read_info()`, found a spot where errors were
   being sent to the global error reporter instead of to the PNG
   reader's own error store.  (It is relevant to this PR because that
   is called by the ICO code for certain ico files that are really
   using PNG encoding.)

3. Handle scanline width that's not 8 pixel multiple without running
   over buffer limits.

4. Guard against possible palette array overrun for 4bpp case.  The 1-
   and 8-bpp palette cases already had computed the palette index and
   checked for being in range before accessing the array. But the
   4-bpp case did not!

Items 1 & 2 were entirely LG. Items 3 & 4 were identified and fixed
with the assistance of Claude Code / Opus 4.6 -- it was really
helpful!  I'm honestly not sure if it saved me 5 hours or closer to 5
minutes, but even if short, it would not have been at all fun to trace
through by hand to find a subtle case that we previously forgot to
check.

Signed-off-by: Larry Gritz <lg@larrygritz.com>
Assisted-by: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Larry Gritz <lg@larrygritz.com>
Signed-off-by: Larry Gritz <lg@larrygritz.com>
@lgritz
Copy link
Collaborator Author

lgritz commented Mar 15, 2026

Updated with even more protections against integer overflow.

Also updated the check_open with the knowledge that for pure ICO files (when it's not a PNG underneath), the max resolution is 256, not 64k.

AND, noticed a longstanding bug for the first time, which is that since the ICO files use a uint8 to store the resolution, it uses 0 to signify 256, which we did not handle properly before.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants