fcl-images: A lot of bugs in most formats, leading to crashes, timeouts, wrong behavior. Code execution in PSD.
Hello, I wanted to report some issues with fcl-image. I will say it directly: all of the issues were found and confirmed by GPT 5.3 Codex + GPT 5.4 in Codex. I'll also attach the raw reports/PoC folders. I hope this is useful, those are not hallucinations. And, as far as I know, Lazarus uses fcl-image in TImage, so those issues apply to a lot of programs. Also, it's likely that no one really uses the PSD decoder (Lazarus doesn't use it), but it's still included in the report. The separate reports + PoC images + LLM writeups are in this archive: [fpc_review_sanitized.zip](/uploads/5e0b51476c8755130ac5b9295bba7f82/fpc_review_sanitized.zip) The report below is a concatenated report of all findings, LLM-written: # fcl-image: consolidated reader/writer issues across BMP, GIF, JPEG, PNG, PNM, PSD, TGA, TIFF, and XPM Tested against upstream `origin/main` at `d50c80a77e21c0f8dab68257ed6f146aedf57a70`. This consolidates the confirmed findings from the review reports in `reports/`, the repro corpus in `pocs/fclimage/`, and the PSD lab notes in `psd/`. ## Critical ### PSD - Indexed palette length is unchecked, and palette parsing can overrun a fixed stack buffer. Affected: [`fpreadpsd.pas:L163`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpsd.pas#L163), [`fpreadpsd.pas:L167`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpsd.pas#L167), [`fpreadpsd.pas:L171`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpsd.pas#L171). PoC: `pocs/fclimage/psd/cases/indexed_palette_overflow_1024.psd`. Additional context: `psd/findings.md` shows saved return-address overwrite and same-process control-flow redirection in a lab build; the same parser family also has unchecked resource-block walking in [`fpreadpsd.pas:L283`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpsd.pas#L283) through [`fpreadpsd.pas:L316`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpsd.pas#L316). ## High ### BMP - Normal BMP loading through the standard fcl-image API is broken and crashes on valid input. Affected: [`fphandler.inc:L252`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fphandler.inc#L252), [`fpreadbmp.pp:L216`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadbmp.pp#L216), [`fpreadbmp.pp:L226`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadbmp.pp#L226). PoC: `pocs/fclimage/bmp/cases/valid_rgb_1x1.bmp`. - Palette handling trusts `ClrUsed` and can overflow heap buffers. Affected: [`fpreadbmp.pp:L201`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadbmp.pp#L201), [`fpreadbmp.pp:L203`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadbmp.pp#L203), [`fpreadbmp.pp:L204`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadbmp.pp#L204), [`fpreadbmp.pp:L272`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadbmp.pp#L272), [`fpreadbmp.pp:L276`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadbmp.pp#L276), [`fpreadbmp.pp:L278`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadbmp.pp#L278). PoC: `pocs/fclimage/bmp/cases/clrused_overflow_1bpp.bmp`. - Width/height and row-size validation is too weak and can reach dangerous allocation/math paths. Affected: [`fpreadbmp.pp:L212`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadbmp.pp#L212), [`fpreadbmp.pp:L241`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadbmp.pp#L241), [`fpreadbmp.pp:L242`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadbmp.pp#L242), [`fpreadbmp.pp:L245`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadbmp.pp#L245), [`fpreadbmp.pp:L254`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadbmp.pp#L254), [`fpreadbmp.pp:L280`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadbmp.pp#L280), [`fpreadbmp.pp:L526`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadbmp.pp#L526), [`fpreadbmp.pp:L528`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadbmp.pp#L528). ### GIF - Truncated extension blocks can hang both `load` and `ImageSize` indefinitely. Affected: [`fpreadgif.pas:L605`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadgif.pas#L605), [`fpreadgif.pas:L617`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadgif.pas#L617), [`fpreadgif.pas:L278`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadgif.pas#L278), [`fpreadgif.pas:L289`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadgif.pas#L289). PoC: `pocs/fclimage/gif/cases/comment_missing_terminator.gif`. - Truncated LZW image data is accepted, and the scanline buffer can be consumed before it is fully initialized. Affected: [`fpreadgif.pas:L171`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadgif.pas#L171), [`fpreadgif.pas:L172`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadgif.pas#L172), [`fpreadgif.pas:L394`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadgif.pas#L394), [`fpreadgif.pas:L414`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadgif.pas#L414), [`fpreadgif.pas:L430`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadgif.pas#L430), [`fpreadgif.pas:L512`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadgif.pas#L512), [`fpreadgif.pas:L552`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadgif.pas#L552), [`fpreadgif.pas:L566`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadgif.pas#L566). PoC: `pocs/fclimage/gif/cases/short_lzw_2x1_truncated_eof.gif`. - Dimension and scanline arithmetic is unchecked and feeds dangerous allocation paths. Affected: [`fpreadgif.pas:L171`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadgif.pas#L171), [`fpreadgif.pas:L251`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadgif.pas#L251), [`fpreadgif.pas:L430`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadgif.pas#L430), [`fpimage.inc:L597`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpimage.inc#L597), [`fpimage.inc:L605`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpimage.inc#L605), [`fpimage.inc:L615`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpimage.inc#L615). ### JPEG - EXIF APP1 parsing trusts attacker-controlled `data_type` / `data_count` values and allocates directly from tag metadata. Affected: [`jdmarker.pas:L1684`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/pasjpeg/src/jdmarker.pas#L1684), [`jdmarker.pas:L1806`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/pasjpeg/src/jdmarker.pas#L1806), [`jdmarker.pas:L1808`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/pasjpeg/src/jdmarker.pas#L1808), [`jdmarker.pas:L1809`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/pasjpeg/src/jdmarker.pas#L1809), [`jdmarker.pas:L1812`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/pasjpeg/src/jdmarker.pas#L1812). PoC: `pocs/fclimage/jpeg/cases/exif_large_count_16m.jpg`. - Maximum-size SOF headers can trigger excessive image allocation and decode-time denial of service. Affected: [`fpreadjpeg.pas:L473`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadjpeg.pas#L473), [`fpreadjpeg.pas:L475`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadjpeg.pas#L475), [`fpreadjpeg.pas:L479`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadjpeg.pas#L479), [`jdinput.pas:L70`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/pasjpeg/src/jdinput.pas#L70). PoC: `pocs/fclimage/jpeg/cases/size_probe_65500x65500.jpg`. ### PNG - `InternalCheck` accepts truncated or malformed first chunks as `IHDR` and passes malformed state into later PNG decode paths. Affected: [`fpreadpng.pp:L163`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpng.pp#L163), [`fpreadpng.pp:L975`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpng.pp#L975), [`fpreadpng.pp:L976`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpng.pp#L976), [`fpreadpng.pp:L895`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpng.pp#L895). PoC: `pocs/fclimage/png/cases/zero_len_first_chunk.png`, `pocs/fclimage/png/cases/short_ihdr_1byte.png`. - Truncated decompressed scanlines are accepted and decoded from uninitialized heap memory. Affected: [`fpreadpng.pp:L838`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpng.pp#L838), [`fpreadpng.pp:L839`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpng.pp#L839), [`fpreadpng.pp:L848`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpng.pp#L848), [`fpreadpng.pp:L849`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpng.pp#L849), [`fpreadpng.pp:L850`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpng.pp#L850), [`fpreadpng.pp:L853`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpng.pp#L853). PoC: `pocs/fclimage/png/cases/filter_only_truecolor.png`. - Header validation is incomplete, so illegal `ColorType` / `BitDepth` combinations reach decode with inconsistent state. Affected: [`fpreadpng.pp:L732`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpng.pp#L732), [`fpreadpng.pp:L791`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpng.pp#L791), [`fpreadpng.pp:L983`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpng.pp#L983). PoC: `pocs/fclimage/png/cases/invalid_colortype_1.png`. - Indexed-color chunk ordering and payload validation are unsafe. Affected: [`fpreadpng.pp:L254`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpng.pp#L254), [`fpreadpng.pp:L268`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpng.pp#L268), [`fpreadpng.pp:L282`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpng.pp#L282), [`fpreadpng.pp:L324`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpng.pp#L324), [`fpreadpng.pp:L362`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpng.pp#L362). PoC: `pocs/fclimage/png/cases/missing_plte_indexed.png`, `pocs/fclimage/png/cases/indexed_trns_before_plte.png`, `pocs/fclimage/png/cases/short_trns_truecolor.png`. ### PNM - Dimensions are trusted blindly and can drive oversized allocation and zero-fill work. Affected: [`fpreadpnm.pp:L183`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpnm.pp#L183), [`fpreadpnm.pp:L184`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpnm.pp#L184), [`fpreadpnm.pp:L190`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpnm.pp#L190), [`fpreadpnm.pp:L216`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpnm.pp#L216), [`fpreadpnm.pp:L222`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpnm.pp#L222), [`fpimage.inc:L597`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpimage.inc#L597), [`fpimage.inc:L605`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpimage.inc#L605), [`fpimage.inc:L615`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpimage.inc#L615). PoC: `pocs/fclimage/pnm/cases/alloc_timeout_65536x65537_raw.pbm`. ### PSD - RLE decode does not bound expanded output to the allocated scanline buffer. Affected: [`fpreadpsd.pas:L226`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpsd.pas#L226), [`fpreadpsd.pas:L228`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpsd.pas#L228), [`fpreadpsd.pas:L363`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpsd.pas#L363), [`fpreadpsd.pas:L406`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpsd.pas#L406), [`fpreadpsd.pas:L423`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpsd.pas#L423), [`fpreadpsd.pas:L425`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpsd.pas#L425), [`fpreadpsd.pas:L431`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpsd.pas#L431), [`fpreadpsd.pas:L435`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpsd.pas#L435). PoC: `pocs/fclimage/psd/cases/rle_overflow_gray_1x1.psd`. Related lab context: `psd/findings.md`. - Width and height are trusted blindly and can drive large allocation and zero-fill work. Affected: [`fpreadpsd.pas:L223`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpsd.pas#L223), [`fpreadpsd.pas:L224`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpsd.pas#L224), [`fpreadpsd.pas:L226`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpsd.pas#L226), [`fpreadpsd.pas:L227`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpsd.pas#L227), [`fpreadpsd.pas:L228`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpsd.pas#L228), [`fpreadpsd.pas:L346`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpsd.pas#L346), [`fpimage.inc:L597`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpimage.inc#L597), [`fpimage.inc:L605`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpimage.inc#L605), [`fpimage.inc:L615`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpimage.inc#L615). PoC: `pocs/fclimage/psd/cases/size_timeout_50000x50000.psd`. ### TGA - Grayscale TGA decoding writes 256 palette entries into a 255-entry allocation. Affected: [`fpreadtga.pp:L121`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadtga.pp#L121), [`fpreadtga.pp:L122`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadtga.pp#L122), [`fpreadtga.pp:L125`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadtga.pp#L125), [`fpreadtga.pp:L137`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadtga.pp#L137), [`fpreadtga.pp:L139`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadtga.pp#L139). PoC: `pocs/fclimage/tga/cases/gray8_ff_1x1.tga`. - Indexed TGA decoding ignores `MapStart`, causing out-of-bounds palette reads on valid files. Affected: [`fpreadtga.pp:L123`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadtga.pp#L123), [`fpreadtga.pp:L124`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadtga.pp#L124), [`fpreadtga.pp:L159`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadtga.pp#L159), [`fpreadtga.pp:L171`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadtga.pp#L171), [`fpreadtga.pp:L280`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadtga.pp#L280), [`fpreadtga.pp:L282`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadtga.pp#L282). PoC: `pocs/fclimage/tga/cases/indexed_mapstart1_red.tga`. ### TIFF - Raw strip/tile reads ignore short reads and can decode uninitialized heap bytes as pixels. Affected: [`fpreadtiff.pas:L2099`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadtiff.pas#L2099), [`fpreadtiff.pas:L2101`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadtiff.pas#L2101), [`fpreadtiff.pas:L2142`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadtiff.pas#L2142), [`fpreadtiff.pas:L2183`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadtiff.pas#L2183). PoC: `pocs/fclimage/tiff/cases/short_raw_rgb_1x1.tiff`. - `ReadShortOrLongValues` mishandles `SHORT` arrays, so valid TIFFs with `SHORT` strip/tile metadata are rejected. Affected: [`fpreadtiff.pas:L1739`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadtiff.pas#L1739), [`fpreadtiff.pas:L1741`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadtiff.pas#L1741), [`fpreadtiff.pas:L1743`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadtiff.pas#L1743), [`fpreadtiff.pas:L2092`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadtiff.pas#L2092), [`fpreadtiff.pas:L2095`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadtiff.pas#L2095). PoC: `pocs/fclimage/tiff/cases/short_stripmeta_valid_1x1.tiff`. - PackBits decode reports the wrong decompressed length, which can bypass length validation and drive out-of-bounds reads. Affected: [`fpreadtiff.pas:L2214`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadtiff.pas#L2214), [`fpreadtiff.pas:L2503`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadtiff.pas#L2503), [`fpreadtiff.pas:L2521`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadtiff.pas#L2521), [`fpreadtiff.pas:L2537`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadtiff.pas#L2537), [`fpreadtiff.pas:L2547`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadtiff.pas#L2547), [`fpreadtiff.pas:L2557`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadtiff.pas#L2557). PoC: `pocs/fclimage/tiff/cases/packbits_length_bypass.tiff`. - Deflate-compressed TIFF data can expand far beyond the declared image size without a hard bound. Affected: [`fpreadtiff.pas:L2231`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadtiff.pas#L2231), [`fpreadtiff.pas:L2241`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadtiff.pas#L2241), [`fpreadtiff.pas:L2804`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadtiff.pas#L2804), [`fpreadtiff.pas:L2841`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadtiff.pas#L2841), [`fpreadtiff.pas:L2850`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadtiff.pas#L2850). PoC: `pocs/fclimage/tiff/cases/deflate_overexpand_1x1.tiff`. ### XPM - Palette lines with missing color payload can crash the parser with an access violation. Affected: [`fpreadxpm.pp:L232`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadxpm.pp#L232), [`fpreadxpm.pp:L235`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadxpm.pp#L235), [`fpreadxpm.pp:L250`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadxpm.pp#L250), [`fpreadxpm.pp:L264`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadxpm.pp#L264), [`fpreadxpm.pp:L266`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadxpm.pp#L266). PoC: `pocs/fclimage/xpm/cases/empty_palette_line.xpm`. - Unchecked width, height, and `cpp` values reach dangerous allocation and CPU paths. Affected: [`fpreadxpm.pp:L206`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadxpm.pp#L206), [`fpreadxpm.pp:L209`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadxpm.pp#L209), [`fpreadxpm.pp:L232`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadxpm.pp#L232), [`fpreadxpm.pp:L274`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadxpm.pp#L274), [`fpreadxpm.pp:L277`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadxpm.pp#L277), [`fpreadxpm.pp:L308`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadxpm.pp#L308), [`fpimage.inc:L597`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpimage.inc#L597), [`fpimage.inc:L605`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpimage.inc#L605), [`fpimage.inc:L615`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpimage.inc#L615), [`fpimage.inc:L651`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpimage.inc#L651), [`fpimage.inc:L654`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpimage.inc#L654). PoC: `pocs/fclimage/xpm/cases/negative_height_invalid_pointer.xpm`, `pocs/fclimage/xpm/cases/size_bomb_50000x50000_cpp0.xpm`. ## Medium ### BMP - `CheckContents` accepts unsupported compression modes that the loader later rejects. Affected: [`fpreadbmp.pp:L238`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadbmp.pp#L238), [`fpreadbmp.pp:L239`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadbmp.pp#L239), [`fpreadbmp.pp:L530`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadbmp.pp#L530). PoC: `pocs/fclimage/bmp/cases/bi_png_check_only.bmp`, `pocs/fclimage/bmp/cases/alphabitfields_check_only.bmp`. - `bfOffset` is effectively ignored during BMP decode. Affected: [`fpreadbmp.pp:L231`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadbmp.pp#L231), [`fpreadbmp.pp:L295`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadbmp.pp#L295), [`fpreadbmp.pp:L302`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadbmp.pp#L302). PoC: `pocs/fclimage/bmp/cases/bfoffset_gap_ignored.bmp`. - Extended DIB header sizes are accepted but not parsed correctly. Affected: [`fpreadbmp.pp:L185`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadbmp.pp#L185), [`fpreadbmp.pp:L231`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadbmp.pp#L231), [`fpreadbmp.pp:L526`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadbmp.pp#L526). PoC: `pocs/fclimage/bmp/cases/header56_bitfields_masks_ignored.bmp`. - Short reads are not checked in many decode paths. Affected: [`fpreadbmp.pp:L187`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadbmp.pp#L187), [`fpreadbmp.pp:L188`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadbmp.pp#L188), [`fpreadbmp.pp:L189`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadbmp.pp#L189), [`fpreadbmp.pp:L204`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadbmp.pp#L204), [`fpreadbmp.pp:L206`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadbmp.pp#L206), [`fpreadbmp.pp:L335`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadbmp.pp#L335), [`fpreadbmp.pp:L352`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadbmp.pp#L352), [`fpreadbmp.pp:L358`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadbmp.pp#L358), [`fpreadbmp.pp:L398`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadbmp.pp#L398), [`fpreadbmp.pp:L418`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadbmp.pp#L418), [`fpreadbmp.pp:L430`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadbmp.pp#L430), [`fpreadbmp.pp:L455`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadbmp.pp#L455). ### GIF - `InternalCheck` only validates the signature/version and accepts files with no image data. PoC: `pocs/fclimage/gif/cases/trailer_only.gif`. - Unknown extension labels are not skipped generically and can desynchronize parsing. Affected: [`fpreadgif.pas:L219`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadgif.pas#L219), [`fpreadgif.pas:L221`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadgif.pas#L221), [`fpreadgif.pas:L603`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadgif.pas#L603), [`fpreadgif.pas:L604`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadgif.pas#L604), [`fpreadgif.pas:L626`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadgif.pas#L626), [`fpreadgif.pas:L328`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadgif.pas#L328). PoC: `pocs/fclimage/gif/cases/unknown_extension_2c.gif`. - `ImageSize` under-skips the global color table and can misreport sizes on valid GIFs. PoC: `pocs/fclimage/gif/cases/palette_blue_2c.gif`. - Valid GIFs with a non-zero background index are decoded as transparent even without a transparency extension. Affected: [`fpreadgif.pas:L156`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadgif.pas#L156), [`fpreadgif.pas:L164`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadgif.pas#L164), [`fpreadgif.pas:L175`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadgif.pas#L175). PoC: `pocs/fclimage/gif/cases/valid_red_bgindex1_transparent.gif`. ### JPEG - `ImageSize` ignores EXIF orientation even though full decode rotates the image. Affected: [`fpreadjpeg.pas:L248`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadjpeg.pas#L248), [`fpreadjpeg.pas:L321`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadjpeg.pas#L321), [`fpreadjpeg.pas:L453`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadjpeg.pas#L453), [`fpreadjpeg.pas:L616`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadjpeg.pas#L616). PoC: `pocs/fclimage/jpeg/cases/valid_rgb_1x2_exif_orient_6.jpg`. - The source manager silently manufactures an EOI marker at EOF. Affected: [`jdatasrc.pas:L121`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/pasjpeg/src/jdatasrc.pas#L121), [`jdatasrc.pas:L125`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/pasjpeg/src/jdatasrc.pas#L125), [`jdatasrc.pas:L127`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/pasjpeg/src/jdatasrc.pas#L127). PoC: `pocs/fclimage/jpeg/cases/truncated_missing_eoi.jpg`. - `InternalCheck` validates only `FFD8`. Affected: [`fpreadjpeg.pas:L639`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadjpeg.pas#L639), [`jdmarker.pas:L2327`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/pasjpeg/src/jdmarker.pas#L2327). PoC: `pocs/fclimage/jpeg/cases/soi_only.jpg`. - Normal JPEG loads fully buffer the input stream in memory before parsing. Affected: [`fpreadjpeg.pas:L141`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadjpeg.pas#L141), [`fpreadjpeg.pas:L152`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadjpeg.pas#L152), [`fpreadjpeg.pas:L583`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadjpeg.pas#L583), [`fpreadjpeg.pas:L584`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadjpeg.pas#L584). - The EXIF parser trusts the IFD offset and can desynchronize parsing beyond the APP1 body. Affected: [`jdmarker.pas:L1776`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/pasjpeg/src/jdmarker.pas#L1776), [`jdmarker.pas:L1782`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/pasjpeg/src/jdmarker.pas#L1782), [`jdmarker.pas:L1786`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/pasjpeg/src/jdmarker.pas#L1786). - `InternalSize` returns uninitialized garbage on empty input. Affected: [`fpreadjpeg.pas:L616`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadjpeg.pas#L616), [`fpreadjpeg.pas:L623`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadjpeg.pas#L623). PoC: `pocs/fclimage/jpeg/cases/empty.jpg`. ### PNG - Invalid filter bytes are not rejected. Affected: [`fpreadpng.pp:L411`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpng.pp#L411), [`fpreadpng.pp:L448`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpng.pp#L448), [`fpreadpng.pp:L850`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpng.pp#L850). PoC: `pocs/fclimage/png/cases/invalid_filter_5.png`. - Dimension and scanline arithmetic lack overflow and resource-limit checks. Affected: [`fpreadpng.pp:L835`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpng.pp#L835), [`fpreadpng.pp:L895`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpng.pp#L895), [`fpwritepng.pp:L510`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpwritepng.pp#L510), [`fpwritepng.pp:L511`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpwritepng.pp#L511), [`fpwritepng.pp:L711`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpwritepng.pp#L711). PoC: `pocs/fclimage/png/cases/size_probe_70000x80000.png`. - `ImageSize` does more than truncate 32-bit dimensions; it also returns arbitrary sizes for malformed PNGs. Affected: [`fpreadpng.pp:L923`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpng.pp#L923), [`fpreadpng.pp:L941`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpng.pp#L941), [`fpreadpng.pp:L945`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpng.pp#L945). PoC: `pocs/fclimage/png/cases/first_chunk_not_ihdr.png`, `pocs/fclimage/png/cases/short_ihdr_1byte.png`, `pocs/fclimage/png/cases/size_probe_70000x80000.png`. - Reader and writer fully buffer PNG image data in memory. Affected: [`fpreadpng.pp:L238`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpng.pp#L238), [`fpreadpng.pp:L896`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpng.pp#L896), [`fpwritepng.pp:L715`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpwritepng.pp#L715), [`fpwritepng.pp:L783`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpwritepng.pp#L783). - The writer emits spec-invalid zero-dimension PNGs instead of rejecting them. Affected: [`fpwritepng.pp:L510`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpwritepng.pp#L510), [`fpwritepng.pp:L511`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpwritepng.pp#L511), [`fpwritepng.pp:L557`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpwritepng.pp#L557), [`fpwritepng.pp:L563`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpwritepng.pp#L563), [`fpwritepng.pp:L883`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpwritepng.pp#L883). PoC: `pocs/fclimage/png/cases/writer_zero_by_zero.png`. - Grayscale-plus-alpha writer packing is incorrect. Affected: [`fpwritepng.pp:L585`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpwritepng.pp#L585), [`fpwritepng.pp:L591`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpwritepng.pp#L591). ### PNM - `InternalCheck` accepts unsupported `P7` input even though the loader only implements `P1..P6`. Affected: [`fpreadpnm.pp:L77`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpnm.pp#L77), [`fpreadpnm.pp:L94`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpnm.pp#L94), [`fpreadpnm.pp:L180`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpnm.pp#L180), [`fpreadpnm.pp:L182`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpnm.pp#L182). PoC: `pocs/fclimage/pnm/cases/p7_check_only.pnm`. - Header integers are truncated to seven digits while consuming the eighth digit. Affected: [`fpreadpnm.pp:L118`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpnm.pp#L118), [`fpreadpnm.pp:L129`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpnm.pp#L129), [`fpreadpnm.pp:L183`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpnm.pp#L183), [`fpreadpnm.pp:L184`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpnm.pp#L184), [`fpreadpnm.pp:L189`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpnm.pp#L189). PoC: `pocs/fclimage/pnm/cases/width_8digits_truncates.pgm`. - Valid raw-header comments after `MaxVal` are treated as pixel bytes. Affected: [`fpreadpnm.pp:L102`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpnm.pp#L102), [`fpreadpnm.pp:L125`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpnm.pp#L125), [`fpreadpnm.pp:L189`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpnm.pp#L189), [`fpreadpnm.pp:L276`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpnm.pp#L276), [`fpreadpnm.pp:L279`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpnm.pp#L279). PoC: `pocs/fclimage/pnm/cases/raw_comment_after_maxval.pgm`. - Text sample values are never validated against `MaxVal` or 16-bit storage. Affected: [`fpreadpnm.pp:L189`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpnm.pp#L189), [`fpreadpnm.pp:L190`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpnm.pp#L190), [`fpreadpnm.pp:L260`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpnm.pp#L260), [`fpreadpnm.pp:L268`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpnm.pp#L268), [`fpreadpnm.pp:L270`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpnm.pp#L270), [`fpreadpnm.pp:L272`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpnm.pp#L272). PoC: `pocs/fclimage/pnm/cases/sample_65536_wraps_to_black.pgm`. ### PSD - Header validation is too weak; unsupported modes pass `CheckContents` and can crash later. Affected: [`fpreadpsd.pas:L214`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpsd.pas#L214), [`fpreadpsd.pas:L222`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpsd.pas#L222), [`fpreadpsd.pas:L459`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpsd.pas#L459), [`fpreadpsd.pas:L471`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpsd.pas#L471), [`fpreadpsd.pas:L475`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpsd.pas#L475), [`fpreadpsd.pas:L600`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpsd.pas#L600), [`fpreadpsd.pas:L612`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpsd.pas#L612). PoC: `pocs/fclimage/psd/cases/invalid_mode_99.psd`. - Valid 16-bit grayscale PSDs are decoded through the indexed-palette path and fail. Affected: [`fpreadpsd.pas:L195`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpsd.pas#L195), [`fpreadpsd.pas:L198`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpsd.pas#L198), [`fpreadpsd.pas:L217`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpsd.pas#L217), [`fpreadpsd.pas:L479`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpsd.pas#L479), [`fpreadpsd.pas:L483`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpsd.pas#L483). PoC: `pocs/fclimage/psd/cases/gray16_valid_1x1.psd`. ### TGA - Valid 16-bit color-map entries are misparsed as 24-bit palette records. Affected: [`fpreadtga.pp:L157`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadtga.pp#L157), [`fpreadtga.pp:L158`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadtga.pp#L158), [`fpreadtga.pp:L161`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadtga.pp#L161). PoC: `pocs/fclimage/tga/cases/indexed_palette16_red.tga`. - Unsupported header combinations pass `CheckContents` and later decode with garbage semantics. Affected: [`fpreadtga.pp:L109`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadtga.pp#L109), [`fpreadtga.pp:L110`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadtga.pp#L110), [`fpreadtga.pp:L343`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadtga.pp#L343), [`fpreadtga.pp:L357`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadtga.pp#L357), [`fpreadtga.pp:L358`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadtga.pp#L358), [`fpreadtga.pp:L359`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadtga.pp#L359). PoC: `pocs/fclimage/tga/cases/indexed_pixelsize24_invalid.tga`. - Indexed images do not require a palette and can load from uninitialized palette memory. Affected: [`fpreadtga.pp:L123`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadtga.pp#L123), [`fpreadtga.pp:L124`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadtga.pp#L124), [`fpreadtga.pp:L206`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadtga.pp#L206), [`fpreadtga.pp:L207`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadtga.pp#L207), [`fpreadtga.pp:L280`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadtga.pp#L280), [`fpreadtga.pp:L282`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadtga.pp#L282). PoC: `pocs/fclimage/tga/cases/indexed_no_palette.tga`. - 32-bit alpha is treated as a one-bit transparency flag. Affected: [`fpreadtga.pp:L173`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadtga.pp#L173), [`fpreadtga.pp:L179`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadtga.pp#L179), [`fpreadtga.pp:L180`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadtga.pp#L180), [`fpreadtga.pp:L181`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadtga.pp#L181), [`fpreadtga.pp:L306`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadtga.pp#L306), [`fpreadtga.pp:L310`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadtga.pp#L310), [`fpreadtga.pp:L311`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadtga.pp#L311), [`fpreadtga.pp:L312`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadtga.pp#L312). PoC: `pocs/fclimage/tga/cases/truecolor32_alpha7f.tga`. ### TIFF - Valid `YCbCrCoefficients` TIFFs are rejected because tag 529 is parsed as three separate single-rational entries. Affected: [`fpreadtiff.pas:L1436`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadtiff.pas#L1436), [`fpreadtiff.pas:L1439`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadtiff.pas#L1439), [`fpreadtiff.pas:L1444`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadtiff.pas#L1444), [`fpreadtiff.pas:L1449`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadtiff.pas#L1449), [`fpreadtiff.pas:L1578`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadtiff.pas#L1578), [`fpreadtiff.pas:L1587`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadtiff.pas#L1587). PoC: `pocs/fclimage/tiff/cases/valid_ycbcr_coeffs_1x1.tiff`. - `CheckContents` accepts impossible first-IFD offsets. Affected: [`fpreadtiff.pas:L612`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadtiff.pas#L612), [`fpreadtiff.pas:L2283`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadtiff.pas#L2283), [`fpreadtiff.pas:L2290`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadtiff.pas#L2290). PoC: `pocs/fclimage/tiff/cases/bad_ifd_offset_only_header.tiff`. - Many structural reads do not check for truncation. Affected: [`fpreadtiff.pas:L621`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadtiff.pas#L621), [`fpreadtiff.pas:L1642`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadtiff.pas#L1642), [`fpreadtiff.pas:L1722`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadtiff.pas#L1722), [`fpreadtiff.pas:L2101`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadtiff.pas#L2101). - Generic value loading uses unchecked size arithmetic. Affected: [`fpreadtiff.pas:L1697`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadtiff.pas#L1697), [`fpreadtiff.pas:L1700`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadtiff.pas#L1700), [`fpreadtiff.pas:L1707`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadtiff.pas#L1707), [`fpreadtiff.pas:L1721`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadtiff.pas#L1721). - The TIFF writer trusts bit-depth extras it cannot actually encode. Affected: [`fpwritetiff.pas:L467`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpwritetiff.pas#L467), [`fpwritetiff.pas:L482`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpwritetiff.pas#L482), [`fpwritetiff.pas:L669`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpwritetiff.pas#L669), [`fpwritetiff.pas:L672`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpwritetiff.pas#L672), [`fpwritetiff.pas:L676`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpwritetiff.pas#L676), [`fpwritetiff.pas:L679`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpwritetiff.pas#L679). PoC: `pocs/fclimage/tiff/cases/writer_graybits1_alpha0.tiff`, `pocs/fclimage/tiff/cases/writer_graybits12_alpha0.tiff`. ### XPM - `InternalCheck` only validates the magic comment and accepts non-images. Affected: [`fpreadxpm.pp:L203`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadxpm.pp#L203), [`fpreadxpm.pp:L322`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadxpm.pp#L322), [`fpreadxpm.pp:L327`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadxpm.pp#L327). PoC: `pocs/fclimage/xpm/cases/comment_only.xpm`. - Undefined pixel codes are silently decoded as palette entry 0. Affected: [`fpreadxpm.pp:L274`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadxpm.pp#L274), [`fpreadxpm.pp:L281`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadxpm.pp#L281), [`fpreadxpm.pp:L290`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadxpm.pp#L290). PoC: `pocs/fclimage/xpm/cases/undefined_code_1x1.xpm`. - Unrecognized named colors silently become transparent. Affected: [`fpreadxpm.pp:L98`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadxpm.pp#L98), [`fpreadxpm.pp:L158`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadxpm.pp#L158), [`fpreadxpm.pp:L253`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadxpm.pp#L253), [`fpreadxpm.pp:L256`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadxpm.pp#L256). PoC: `pocs/fclimage/xpm/cases/named_orange_1x1.xpm`. ## Low ### BMP - 32-bpp alpha is inverted on read. Affected: [`fpreadbmp.pp:L90`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadbmp.pp#L90), [`fpreadbmp.pp:L91`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadbmp.pp#L91), [`fpwritebmp.pp:L95`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpwritebmp.pp#L95). PoC: `pocs/fclimage/bmp/cases/rgba_alpha_inverted_1x1.bmp`. - `ImageSize` returns negative height for top-down BMPs. Affected: [`fpreadbmp.pp:L552`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadbmp.pp#L552), [`fpreadbmp.pp:L554`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadbmp.pp#L554). PoC: `pocs/fclimage/bmp/cases/topdown_negative_height.bmp`. - BMP writer mutates caller-owned resolution metadata during save. - Writer size calculations can overflow on large images. Affected: [`fpwritebmp.pp:L675`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpwritebmp.pp#L675), [`fpwritebmp.pp:L682`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpwritebmp.pp#L682), [`fpwritebmp.pp:L279`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpwritebmp.pp#L279). ### GIF - Transparency indices are not validated against the active palette before mutation. Affected: [`fpreadgif.pas:L167`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadgif.pas#L167), [`fpreadgif.pas:L175`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadgif.pas#L175). - Structural reads throughout the reader are unchecked. Affected: [`fpreadgif.pas:L129`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadgif.pas#L129), [`fpreadgif.pas:L200`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadgif.pas#L200), [`fpreadgif.pas:L228`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadgif.pas#L228), [`fpreadgif.pas:L379`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadgif.pas#L379), [`fpreadgif.pas:L385`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadgif.pas#L385), [`fpreadgif.pas:L406`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadgif.pas#L406), [`fpreadgif.pas:L600`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadgif.pas#L600), [`fpreadgif.pas:L603`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadgif.pas#L603), [`fpreadgif.pas:L614`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadgif.pas#L614). ### JPEG - The writer buffers output in memory and sets the error manager in the wrong order. Affected: [`fpwritejpeg.pas:L117`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpwritejpeg.pas#L117), [`fpwritejpeg.pas:L119`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpwritejpeg.pas#L119), [`fpwritejpeg.pas:L201`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpwritejpeg.pas#L201), [`jcapimin.pas:L51`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/pasjpeg/src/jcapimin.pas#L51). - JPEG errors are collapsed to a generic message. Affected: [`fpreadjpeg.pas:L169`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadjpeg.pas#L169), [`fpwritejpeg.pas:L68`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpwritejpeg.pas#L68). ### PNG - `pHYs` handling has correctness bugs and writer-side object mutation. Affected: [`fpreadpng.pp:L317`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpng.pp#L317), [`fpreadpng.pp:L320`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpng.pp#L320), [`fpwritepng.pp:L686`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpwritepng.pp#L686), [`fpwritepng.pp:L691`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpwritepng.pp#L691). ### PNM - ASCII PBM accepts values other than `0` and `1` and silently coerces them. Affected: [`fpreadpnm.pp:L251`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpnm.pp#L251), [`fpreadpnm.pp:L252`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpnm.pp#L252). PoC: `pocs/fclimage/pnm/cases/pbm_value_2_becomes_white.pbm`. ### PSD - 8-bit grayscale PSDs decode slightly darker than they should. Affected: [`fpreadpsd.pas:L133`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpsd.pas#L133), [`fpreadpsd.pas:L139`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpsd.pas#L139), [`fpreadpsd.pas:L140`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpsd.pas#L140), [`fpreadpsd.pas:L141`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpsd.pas#L141). PoC: `pocs/fclimage/psd/cases/gray8_max_255_dark.psd`. - Structural reads in the palette and resource paths are widely unchecked. Affected: [`fpreadpsd.pas:L167`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpsd.pas#L167), [`fpreadpsd.pas:L187`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpsd.pas#L187), [`fpreadpsd.pas:L283`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpsd.pas#L283), [`fpreadpsd.pas:L287`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpsd.pas#L287), [`fpreadpsd.pas:L336`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpsd.pas#L336), [`fpreadpsd.pas:L352`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpsd.pas#L352), [`fpreadpsd.pas:L357`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadpsd.pas#L357). ### TGA - 8-bit grayscale values are scaled incorrectly. Affected: [`fpreadtga.pp:L141`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadtga.pp#L141), [`fpreadtga.pp:L142`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadtga.pp#L142), [`fpreadtga.pp:L143`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadtga.pp#L143). PoC: `pocs/fclimage/tga/cases/gray8_ff_1x1.tga`. - The TGA writer silently truncates image dimensions to 16 bits. Affected: [`fpwritetga.pp:L66`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpwritetga.pp#L66), [`fpwritetga.pp:L67`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpwritetga.pp#L67), [`fpwritetga.pp:L86`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpwritetga.pp#L86). PoC: `pocs/fclimage/tga/cases/writer_width70000.tga`. ### TIFF - Writer mutates caller-owned TIFF metadata extras while saving. Affected: [`fpwritetiff.pas:L436`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpwritetiff.pas#L436), [`fpwritetiff.pas:L437`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpwritetiff.pas#L437), [`fpwritetiff.pas:L438`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpwritetiff.pas#L438). - Writer uses unchecked image/chunk size arithmetic. Affected: [`fpwritetiff.pas:L543`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpwritetiff.pas#L543), [`fpwritetiff.pas:L606`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpwritetiff.pas#L606), [`fpwritetiff.pas:L623`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpwritetiff.pas#L623), [`fpwritetiff.pas:L631`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpwritetiff.pas#L631), [`fpwritetiff.pas:L633`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpwritetiff.pas#L633). ### XPM - Odd-length hexadecimal colors are silently truncated instead of rejected. Affected: [`fpreadxpm.pp:L90`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadxpm.pp#L90), [`fpreadxpm.pp:L94`](https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/fcl-image/src/fpreadxpm.pp#L94). PoC: `pocs/fclimage/xpm/cases/odd_hex_len_1234.xpm`.
issue