Skip to content

Fix client crash when decoding malformed PNG data#5052

Open
HeresHavi wants to merge 1 commit into
multitheftauto:masterfrom
HeresHavi:fix-malformed-png-crash
Open

Fix client crash when decoding malformed PNG data#5052
HeresHavi wants to merge 1 commit into
multitheftauto:masterfrom
HeresHavi:fix-malformed-png-crash

Conversation

@HeresHavi

@HeresHavi HeresHavi commented Jul 13, 2026

Copy link
Copy Markdown

Summary

Added recoverable error handling to PngDecode.

Malformed PNG data now returns false instead of reaching libpng's fatal error path and terminating the client. PNG reads that extend beyond the supplied buffer are also rejected safely.

Motivation

MTA builds libpng without its normal setjmp recovery support. When libpng found a fatal decoding error, its default handler called abort() and closed the client.

For example, a resource might download an image and pass its bytes to dxGetPixelsSize or dxConvertPixels. If the image has a damaged PNG chunk or was cut off during download, processing it could crash the player's client.

Crash Stack
Exception: Stack buffer overrun

abort
png_longjmp
png_default_error
png_error
png_chunk_error
png_crc_finish_critical
png_crc_finish
png_handle_IHDR
png_handle_chunk
png_read_info
PngDecode
PngGetDimensions
CPixelsManager::GetPixelsSize
CLuaDrawingDefs::DxGetPixelsSize
Crash

The dialog labels this as a stack buffer overrun, but the stack shows that the client was terminated by libpng's abort() path.

Test plan

Runtime

  • Before Fix: A PNG with a corrupted IHDR CRC terminated the client through png_longjmp and abort.
  • After Fix: The same malformed PNG returned false, and the client stayed open.
  • Valid Case: A valid 1×1 RGB PNG returned the correct dimensions and converted into plain pixels.
  • Corrupt Image Data: A damaged IDAT stream returned false after the output buffers had been allocated, and the client stayed open.
  • Short Input: An IDAT chunk declaring more data than the supplied buffer returned false, and the client stayed open.

Builds and Tests

  • Debug | Win32: Full build passed, 304 client tests passed.
  • Release | Win32: Full build passed.
  • Debug | x64: Full build passed.
  • Release | x64: Full build passed.
  • Ran clang-format.

Checklist

  • Your code should follow the coding guidelines.
  • Smaller pull requests are easier to review. If your pull request is beefy, your pull request should be reviewable commit-by-commit.

Handle fatal libpng decoding errors locally and reject reads beyond the supplied pixel buffer, allowing malformed PNG data to return false instead of terminating the client.
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.

1 participant