Repository navigation
[V4] Fix GIF LZW table bounds and frame clipping - #3253
Merged
Merged
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.
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.
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
Backport #3224, including its review corrections, to current release/4.1.x. Keep this draft until the main fix is merged.
Clip frame geometry to the logical screen, preserve visible rows from later interlace passes, and skip empty passes in short frames. Use the existing sub-block skipper when a frame has no visible pixels.
Reject the invalid first LZW code before indexing the code tables. Strict and IgnoreAncillary throw InvalidImageContentException. IgnoreImageData retains completed rows and skips the rest of the corrupt frame, then continues to the next frame. Header and palette parsing stay outside this recovery boundary. Dispose the partially decoded image when decoding fails.
All new inputs are stored files: the same 17 verified GIFs used by the main fix, totaling 2,310 bytes. Tests cover invalid codes before and after a clear, hidden-row index skipping, all integrity modes, short and clipped interlaced frames, and later animation frames. No test-time input generation remains in the added tests.
Verification
Backports #3224. Addresses #3236 for V4.