# Decoder buffer sized from wrong dimensions

Native decoder wrapper sizes output buffer from requested or declared geometry, not the geometry the library actually writes

_Area: Memory corruption and native code. Seen in 2 disclosed reports; latest 2026-10-20. Updated 2026-10-24._

## How it works
A wrapper around a native decoder pre-computes how large the output buffer must be, then trusts that the library will write exactly that much. The assumption that breaks: the buffer size is derived from one source of truth (a requested scale factor, a declared pixel mode, a nominal row width) while the library writes according to another (the stream's real geometry, the transform's real output format, the sample packing it actually uses). When the two disagree, the write exceeds the allocation.

## Where it shows up
- Wrapper sets a scale/format/geometry parameter on the library, then allocates from that parameter without re-reading what the library reports back (output_width/height/components, stride, bytes-per-pixel).
- Caller-supplied destination objects accepted with only dimension checks; pixel mode/stride not validated against the transform's output format.
- Codec families where a parameter is silently ignored or reinterpreted: lossless/arithmetic modes, sub-byte sample precision, mismatched component resolutions.
- Upload-to-thumbnail paths that hand data to native converters (ImageMagick, Ghostscript, codec libraries) far from the visible handler.

## How to review
The invariant: the allocation size must be computed from the same geometry the library will actually write, and that geometry must be re-validated after the library reports it. Check that (a) every buffer allocation is followed by a comparison of the library's reported output dimensions/components/stride against the allocated size before any write, and (b) for caller-supplied destinations, the actual mode and stride are checked, not just width/height. For each codec/mode the wrapper accepts, confirm the requested parameter is honored; if it can be ignored, the wrapper must detect that.

## Variants seen
- Requested scale factor ignored by the library for a stream subtype, so a shrunk buffer receives full-size rows [E1](https://bugbountylibrary.com/r/ghsa%3AGHSA-8g5g-8vmr-9782.md).
- Row-fill loop writes one byte per sample instead of packing sub-byte samples, overflowing a correctly-sized buffer [E2](https://bugbountylibrary.com/r/blog%3Awordfence-com-blog-2026-10-wordfence-argus-discovers-critical-vulnerability-in-ghostscript-the-program-that-turns-upload.md).
- Transform output format (4 bytes/px) written into a destination allocated for 1 byte/px because only dimensions were validated [E3](https://bugbountylibrary.com/r/ghsa%3AGHSA-9hw9-ch79-4vh6.md).

## Impact and severity
Heap buffer overflow with attacker-influenced contents, reachable from ordinary file upload or image processing; in the Ghostscript case it yielded RCE through a PDF-to-thumbnail feature [E2](https://bugbountylibrary.com/r/blog%3Awordfence-com-blog-2026-10-wordfence-argus-discovers-critical-vulnerability-in-ghostscript-the-program-that-turns-upload.md). Severity rises when the path crosses from a web handler into native converters, and when the trigger hides in internal image geometry rather than obvious malformed input [E2](https://bugbountylibrary.com/r/blog%3Awordfence-com-blog-2026-10-wordfence-argus-discovers-critical-vulnerability-in-ghostscript-the-program-that-turns-upload.md).

## Evidence
- E1: https://bugbountylibrary.com/r/ghsa%3AGHSA-8g5g-8vmr-9782.md
- E2: https://bugbountylibrary.com/r/blog%3Awordfence-com-blog-2026-10-wordfence-argus-discovers-critical-vulnerability-in-ghostscript-the-program-that-turns-upload.md
- E3: https://bugbountylibrary.com/r/ghsa%3AGHSA-9hw9-ch79-4vh6.md
