Repository navigation
P1: Refuse to reload a bitmap slot with a file of a different size or format - #7885
Open
dustinspace217 wants to merge 1 commit into
Open
dustinspace217 wants to merge 1 commit into
dustinspace217 wants to merge 1 commit into
Conversation
Streamed EFF animations reuse one bitmap slot for every frame: bm_reload only swapped the filename, and the lock functions then read the new file into a buffer sized for the slot's first file. A later frame that was bigger (a 32-bit DDS after a 24-bit one, or larger dimensions) wrote past that buffer and corrupted the heap. bm_reload now opens the new file with the slot's own extension, reads its header and refuses it unless width, height, bit depth, compression and mipmap count match the slot, so the caller keeps the last frame that fit.
This was referenced Oct 17, 2026
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.
Fixes #7883
What?
bm_reloadrefuses a file whose size or format differs from the bitmap slot it is being loaded into, so a streamed EFF frame that is bigger than the frames before it no longer corrupts memory.Why?
Main hall animations, ship and weapon selection icons and other streamed EFF animations crash the game when a later frame is bigger than the first ones (a 32-bit DDS after 24-bit ones, or larger dimensions), on OpenGL and Vulkan alike.
How?
Streaming reuses one bitmap slot for every frame.
bm_reloadonly swapped the filename, and the lock functions then read the new file into a buffer sized for the slot's first file.bm_reloadnow opens the new file with the slot's own extension, reads its header and refuses it unless width, height, bit depth, compression and mipmap count match the slot; the caller then keeps the last frame that fit. It doesn't comparemem_taken, becausebm_lock_pcxrewrites that to the size it locked at.bm_reloadhas no other callers.Screenshots?
Testing?
Retail FS2 data, a test mod replacing the main hall's
2_maincraneEFF, 1024x768, Linux Debug builds, master against this branch on OpenGL and Vulkan:Not covered: KTX frames (no tool here to make them; same header path as DDS).
Anything Else?
A first frame bigger than the rest is a different path (the stream's texture is made from frame 0); #7886, which gives EFF streams their own buffer, handles it. The two are meant to land together: this guard is still needed alongside #7886 because the overflow happens in the lock, before the stream sees the frame. The check costs one header read per streamed frame, next to the full decode that follows. A refused frame logs a line each time it comes around in a loop. Written with Claude Code; the investigation, review and testing ran on my machine.