pillow 12.3.0
- Source
- https://github.com/python-pillow/Pillow
- Tag scanned
12.3.0- Compared with
12.2.0(1 signals introduced since)- Files
- 598 scanned, 1152 skipped (binary, oversized, or unrecognised)
- Signals
- 1 critical · 1 warn · 59 info
- Scan time
- 36.7 s
- LLM review
- Reviewed by claude-haiku-5-5 (Anthropic): 56 of 56 warn and critical signals; 54 demoted to info.
- Disclude version
- 4.0.0
- Scanned (UTC)
- 2026-10-14 18:18
Signals
Ordered by severity, then signals introduced in this release. Hidden characters are shown as ⟨U+…⟩.
-
# nosec return 1suspicious Image viewer plugin launches an external viewer via os.system with a constructed command.Reasoning
os.system runs a command built by a viewer plugin's get_command from a file path. This is a shell invocation with a runtime-determined command, but it is the standard image-viewer launch path in Pillow, and the file path is caller-supplied. The critical severity is over-stated for legitimate code, though command injection via file names is a real concern.
-
=likely benign ImageMath compiles user-supplied expression strings for evaluation as a documented feature.Reasoning
compile is called on the expression argument to evaluate image math expressions, which is a documented feature. The expression is a user-supplied math string, not a remote payload, but it is still dynamic code execution in a library, so it warrants a note.
-
info
warn→ info by reviewdecoder-decompress-payloadsrc/PIL/PdfParser.py:331:20new in this release= =likely benign PDF parser decompresses FlateDecode streams as part of normal PDF parsing.Reasoning
zlib decompressobj on FlateDecode streams is the standard PDF filter implementation for parsing PDF content, not a hidden payload dropper.
-
, , )likely benign Test helper runs a literal find command via shell to list fuzz corpus files.Reasoning
Test harness running a fixed find command with shell=True to enumerate test image files; the command is a literal with no external input, typical of oss-fuzz test setup.
-
likely benign Test parametrization runs a literal find command via shell to enumerate font files.
Reasoning
Same pattern as the sibling finding: a literal find command in a test parametrization over font test files, no untrusted input.
-
=likely benign Test fixture embedding a small binary TIFF file as a bytes literal.Reasoning
A bytes literal of a TIFF file header and structure is used as in-memory test input to BytesIO; escape density is natural for binary fixtures.
-
=likely benign Test fixture containing a serialized PIL PngImageFile pickle as a bytes literal.Reasoning
A pickle byte stream for a PIL PNG image is used as a regression test input for pickle.loads; this is test data for a known image-pickling format.
-
if ; then LIBAVIF_CMAKE_FLAGS+=(-DAVIF_CODEC_AOM=SYSTEM) HAS_ENCODER=1 -
if ; then LIBAVIF_CMAKE_FLAGS+=(-DAVIF_CODEC_DAV1D=SYSTEM) HAS_DECODER=1 -
if ; then LIBAVIF_CMAKE_FLAGS+=(-DAVIF_CODEC_LIBGAV1=SYSTEM) HAS_DECODER=1 -
if ; then LIBAVIF_CMAKE_FLAGS+=(-DAVIF_CODEC_RAV1E=SYSTEM) HAS_ENCODER=1 -
if ; then LIBAVIF_CMAKE_FLAGS+=(-DAVIF_CODEC_SVT=SYSTEM) HAS_ENCODER=1 -
}: =likely benign Build script looks up library root objects by name through globals().Reasoning
Reads a root object from globals() by a name drawn from a fixed dict of library roots during build-time dependency detection. Dynamic but benign in a setup script; the name source is internal, not attacker-controlled.
-
=likely benign Module-level loop assigns compression constants into vars() from a static dict.Reasoning
Populates module-level names from the COMPRESSIONS dict at import time, a common Python idiom for generating constants. The keys are fixed in-source.
-
likely benign Base64-encoded PNG image embedded in source, likely in a docstring or example.
Reasoning
A base64 PNG blob in a docstring or doctest-like example of an embedded image; the raw pass has a high false-positive rate for base64 image data in documentation.
-
= rb = rb = rb = rblikely benign Regex character class using octal escapes for PDF delimiter and whitespace bytes.Reasoning
Octal escapes in a regex character class define PDF whitespace and delimiter sets; this is the expected way to write those control bytes in a raw regex.
-
= rb = rb = rb = + blikely benign Regex patterns using octal escapes for PDF whitespace and delimiter bytes.Reasoning
Same as the sibling finding: octal escapes for PDF whitespace bytes in regex patterns, a legitimate parser idiom.
-
= rb = rb = + b = + blikely benign A bytes regex character class listing PDF whitespace control characters via octal escapes.Reasoning
Octal escapes inside a regex character class for PDF whitespace bytes (NUL, tab, LF, FF, CR, space) are a standard, readable way to express those control bytes in a bytes regex. Nothing is decoded or executed.
-
= =likely benign Size-limited zlib decompression of PNG text chunk data.Reasoning
This is Pillow's bounded zlib decompression for PNG text chunks (iTXt/zTXt), capped by MAX_TEXT_CHUNK to prevent decompression bombs. It decompresses the image file's own chunk data, which is the expected format behavior, not a hidden embedded payload.
-
# default palette taken from piffo 0.93 by Hans Häggström b b blikely benign A default RGB palette table embedded as a bytes constant in the WAL image loader.Reasoning
This is a default 256-colour palette (768 bytes of RGB triplets) from a credited source, embedded as a bytes literal in an image-format module. Palette tables are binary data by nature, and this is not executed or decoded into code.
-
b b b blikely benign Part of the default palette byte table in WalImageFile.Reasoning
Continuation of the same palette byte literal; monotone-ish RGB values consistent with palette data. Raw-pass hex-escape flag is a false positive on legitimate binary constant data.
-
b b b blikely benign More rows of the default palette byte table.Reasoning
Additional rows of the same palette constant, with no executable or decoding context. Hex-escape density is expected for binary tables.
-
b b b blikely benign Further rows of the default palette byte table.Reasoning
Same palette constant continuing; the byte values are plausible colour data and the code only indexes into it.
-
b b b blikely benign Further rows of the default palette byte table.Reasoning
Same palette constant, part of the 768-byte table; legitimate static data.
-
b b b blikely benign Further rows of the default palette byte table.Reasoning
Continuation of the palette constant with no code-execution context; benign binary table.
-
b b b )likely benign Final rows of the default palette byte table.Reasoning
Tail of the palette constant, closing the bytes literal. Static data, no decoding into code.
-
b b )likely benign Last row of the default palette byte table.Reasoning
Final line of the same palette literal; benign static colour data.
-
return Truelikely benign Optional-module probe via __import__ in Pillow's features check.Reasoning
Pillow's feature-detection code uses __import__ on a module name to probe whether optional codec/library modules are installed; the module name comes from internal constants, not untrusted input. Legitimate pattern, though dynamic import is worth noting.
-
returnlikely benign Dynamic import to read a dependency version attribute.Reasoning
Same feature-probing pattern: __import__ with fromlist to fetch a version attribute from an optional dependency. Module names are internal constants in Pillow.
-
= returnlikely benign Dynamic import of optional feature module to check a flag.Reasoning
Imports a module named by a flag-to-module mapping within Pillow's feature check and reads an attribute; consistent with legitimate optional-feature detection.
-
returnlikely benign Dynamic import to fetch a library version.Reasoning
Duplicate of the version-probe pattern in features.py; internal module names only, standard for Pillow.
-
; func = ; iflikely benign dlsym resolves Tk/Tcl function pointers at runtime.Reasoning
Dynamic symbol lookup via dlsym in Pillow's Tk integration loads Tcl/Tk functions from a loaded library; the names are internal constants. Legitimate, though dlsym is a dynamic-resolution pattern.
-
/* Try loading from the main program namespace first */ main_program = ; iflikely benign dlopen of the main program handle to find Tk symbols.Reasoning
dlopen(NULL) to search the main program's symbols first is a standard idiom for locating already-loaded Tk symbols; no untrusted path involved.
-
} tkinter_lib = ; iflikely benign dlopen of the tkinter library for ImageTk bindings.Reasoning
Loads the tkinter shared library by a computed name to bind Tk functions; standard for Pillow's ImageTk. Path derived from installed Tk, not attacker input.
-
static struct ImagingAccessInstance accessors =dismissed Mode-constant identifiers flagged for skeleton collision in accessor table.Reasoning
The identifiers IMAGING_MODE_* and similar are visually confusable only due to the tokenizer's skeleton normalization (I/l/1, O/0 letters in ALL-CAPS macro names). Ordinary C macro naming; no homoglyph evidence in the snippet.
-
if else ifdismissed Mode constants flagged by confusable-skeleton heuristic.Reasoning
Same IMAGING_MODE_ identifier collision from the skeleton heuristic; ordinary macro names with no non-ASCII homoglyphs shown.
-
int d; int x0, y0; int xmin, ymin, xmax, ymax; float dx;dismissed Short coordinate identifiers flagged as confusable.Reasoning
Variables xo/yo collapsing from x0/y0 or similar: a false positive from the 0/O normalization of short coordinate names; plain ASCII drawing code.
-
int d; int x0, y0; int xmin, ymin, xmax, ymax; float dx;dismissed Coordinate identifier flagged by confusable-skeleton heuristic.Reasoning
Same as the sibling finding: x0/y0-style coordinate names trip the digit/letter skeleton heuristic; no homoglyphs.
-
static inline voiddismissed Coordinate parameter flagged by confusable-skeleton heuristic.Reasoning
Parameter names x0/y0 normalize to the same skeleton as other identifiers; false positive from digit-letter folding in plain ASCII code.
-
static inline voiddismissed Coordinate parameter flagged by confusable-skeleton heuristic.Reasoning
Parameter y1/y0 style names collide under the digit-letter folding; no homoglyph characters present in snippet. False positive.
-
int32_t py, pl, pr; int32_t cy, cl, cr; int8_t bufcnt; int8_t finished;dismissed Short local identifiers in Pillow's Draw.c collide under a visual confusable skeleton.Reasoning
Skeleton collision on short identifiers like cl/cr/c1 in a Pillow drawing routine is a typical false positive from the confusable heuristic; the snippet shows ordinary per-channel arrays.
-
voiddismissed Angle normalization helper with a confusable-name collision on its parameters.Reasoning
normalize_angles takes float pointers and performs ordinary angle arithmetic; the collision of a and l-style names is a heuristic artifact with no malicious content.
-
ifdismissed Imaging mode validation check flagged for mode-constant name similarity.Reasoning
The skeleton collision is between IMAGING_MODE_ constants that differ only by a mode letter and standard capitalization; ordinary mode validation code.
-
Imaging imIn, int x0, int y0, int x1,dismissed Coordinate parameter names in Geometry.c collide under confusable skeleton matching.Reasoning
Parameters x0/x1 and xo-style names are standard coordinate parameters in a geometry routine; the collision is a heuristic false positive.
-
int x0, int y0, int x1, int y1,dismissed Coordinate parameter names in Geometry.c flagged for visual similarity.Reasoning
y0/y1 style coordinate parameters in a standard image geometry function; no obfuscation evident.
-
likely benign Platform header maps inline to __inline for MSVC compilers.
Reasoning
Defining inline as __inline under MSVC is a long-standing portability idiom in CPython-family headers, not malicious keyword abuse.
-
likely benign Macro alias naming float type as FLOAT32 for pixel-type definitions.
Reasoning
Mapping FLOAT32 to float is a standard typedef-like macro for fixed-width type naming in image code; no hidden payload or execution.
-
likely benign Macro alias naming double type as FLOAT64 for pixel-type definitions.
Reasoning
Same as FLOAT32: a benign type-name macro for the double type in a portable header.
-
= , = , = , = , = , = ,dismissed Mode-name lookup table flagged for confusable identifier similarity.Reasoning
Mode name table with IMAGING_MODE_ identifiers; the skeleton collision is from capitalization and the letter I/l, a heuristic false positive.
-
= , = , = ,dismissed Raw mode name table flagged for confusable identifier similarity.Reasoning
Rawmode name table of standard Pillow constants; no obfuscation evident.
-
= , = , = ,dismissed Raw mode table with packing-format suffixes flagged for name collision.Reasoning
Rawmode table entries such as 1;I and 1;8 differ by pack-format suffix; the collision is a heuristic artifact of the enum naming.
-
IMAGING_MODE_1, IMAGING_MODE_CMYK, IMAGING_MODE_F,dismissed Image mode enum flagged for confusable identifier skeleton.Reasoning
Enum of standard image mode constants in a header; the collision is a naming artifact, not a threat.
-
// Non-rawmode aliases. IMAGING_RAWMODE_1, IMAGING_RAWMODE_CMYK, IMAGING_RAWMODE_F,dismissed Raw mode enum aliases flagged for confusable identifier skeleton.Reasoning
Rawmode enum alias block in a standard header; benign naming collision.
-
// Rawmodes IMAGING_RAWMODE_1_8, IMAGING_RAWMODE_1_I, IMAGING_RAWMODE_1_IR,dismissed Pillow raw-mode enum constants for 1-bit and 8-bit image layouts.Reasoning
The identifiers IMAGING_RAWMODE_1_8, IMAGING_RAWMODE_1_I and IMAGING_RAWMODE_1_IR are ordinary Pillow raw-mode enum names. The 1/I and 8/O-style collision is an artifact of the confusable-skeleton heuristic, which treats 1, I and l as equivalent. No obfuscation or execution is present.
-
/* bilevel */ , , ,dismissed Pack table entry for 1-bit image mode with raw-mode variants.Reasoning
The table maps IMAGING_MODE_1 to IMAGING_RAWMODE_1 and to variants such as _I and _R with pack functions. The skeleton collision comes from 1 versus I in the naming scheme. This is normal image-packing dispatch code.
-
/* bilevel */ , , ,dismissed Pack table entry for the RAWMODE_1 variants.Reasoning
Same table as the previous finding, with the same legitimate 1-bit raw-mode naming. The confusable match is a heuristic false positive from 1/I/l overlap in Pillow's identifiers.
-
ifdismissed Storage setup branch for 1-bit image mode.Reasoning
A plain comparison of mode against IMAGING_MODE_1 followed by setting bands and pixelsize to 1 for 1-bit images. Standard image-storage logic with no suspicious behavior.
-
static voiddismissed Static unpack function for 1-byte-per-pixel boolean image data.Reasoning
The function name unpack18 and its comment describing a numpy boolean ('|b1') unpacking are legitimate Pillow code. The skeleton collision is a false match on the digits 1 and 8 in the name.
-
/* bilevel */ , , ,dismissed Unpack table entry for 1-bit image mode.Reasoning
Unpack dispatch table with the same legitimate 1-bit mode naming as the Pack.c entries. The collision is a confusable-heuristic false positive.
-
/* bilevel */ , , ,dismissed Unpack table entry for RAWMODE_1 variants.Reasoning
Unpack table entry for the RAWMODE_1 variants, consistent with the rest of the file. No dynamic execution or encoded payload is involved.
-
, , /* grayscale */dismissed Unpack table entry for additional 1-bit raw-mode variants.Reasoning
Unpack table entry for the RAWMODE_1_IR and RAWMODE_1_8 variants, which are ordinary Pillow mode names. The collision is a heuristic false positive from character confusability.
Reproduce This Scan
Run disclude locally to verify. Add --format sarif for SARIF output. Add --llm (with an API key in the environment) to include the LLM review.
&&