Repository navigation
Drop GIF frame rows outside the logical screen and stop on LZW codes past the code tables - #3224
Merged
JimBobSquarePants merged 3 commits intoOct 27, 2026
Conversation
…past the code tables An interlaced frame whose lines fall below the logical screen clamped the target row to the screen height and threw from the row lookup, frames shorter than five lines wrote their lines to the wrong rows, and a frame starting right of the screen threw while slicing the row. Lines below the screen are now decoded and discarded only while a later interlace pass can still reach the screen, and frames starting outside the screen are skipped. With a minimum code size of 12 the first code after a clear code could index past the 4096-entry LZW tables. Decoding and skipping now stop at such a code.
3 of 4 tasks
Reject detected out-of-table LZW codes with InvalidImageContentException. Only IgnoreImageData recovers by retaining completed rows and using the existing sub-block skipper. Keep header and palette parsing outside recovery. Dispose the partially decoded image when decoding fails; the new stored regressions reproduce the missing cleanup on the original main branch. Replace all input generation introduced by this PR with 17 stored GIFs (2310 bytes). Independently verify descriptors, palettes, sub-block boundaries, and malformed code sequences. Pillow checks every geometry fixture's frame samples and following white-pixel frame. Cover code errors before and after clear, hidden-row index skipping, all integrity modes, clipped interlace passes, short interlace passes, and continued animation parsing. Current main fails 13 of the 19 new cases. Release .NET 10: 158 GIF tests and 60 GIF-related/shared decoder tests pass. Final focused run: 19 passed. No reference images or tolerances changed.
4 tasks done
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Prerequisites
Description
Clip GIF frame rows and columns to the logical screen without losing visible rows from later interlace passes. Skip empty interlace passes in short frames. Frames entirely outside the screen leave their data to the existing sub-block skipper.
Check the first LZW code before indexing the 4096-entry tables. A tolerated minimum code size of 12 can produce code 4098 before any literal, or after a clear code. This previously threw IndexOutOfRangeException in both Load and Identify.
Detected out-of-table codes now throw InvalidImageContentException. Strict and IgnoreAncillary reject the corrupt image data. IgnoreImageData retains completed rows and skips the rest of that frame, then continues the animation. Header and palette parsing stay outside this recovery boundary. Existing canvas-clipping compatibility remains unchanged.
Dispose a partially decoded image when decoding fails. The stored regressions also reproduced an undisposed pixel buffer on the previous failure paths.
Testing
All new test inputs are stored files: 17 GIFs, 2,310 bytes total. No GIF writer, LZW encoder setup or input generation remains in the added tests. The fixtures cover code errors before and after a clear, an invalid code in a hidden interlace row, clipped and short interlace passes, and fully hidden frames. Every geometry fixture has a following frame to verify continued animation parsing.
Headers, palettes, sub-block boundaries and malformed code sequences were independently checked. Pillow verifies every geometry fixture's frame samples and following white-pixel frame. Interlace row order follows GIF89a Appendix E: https://www.w3.org/Graphics/GIF/spec-gif89a.txt
Current main fails 13 of the 19 new regression cases.
Release .NET 10 verification:
No tolerances or reference images changed. The branch includes current main.
Fixes #3236.