- Replace bailout on OOM with UnwindExit
- Properly reset various globals that may be accessed during startup
Fix GHSA-w8hw-w9fx-j79w (CVE-2026-109618)
Fix GHSA-6wmf-4rv5-p3rp (CVE-2026-109619)
Co-authored-by: Ilija Tovilo <ilija.tovilo@me.com>
Co-authored-by: Jakub Zelenka <bukka@php.net>
Co-authored-by: Nora Dossche <7771979+ndossche@users.noreply.github.com>
Co-authored-by: Nicolas Grekas <nicolas.grekas@gmail.com>
Apply the changes from libgd/libgd@9fa3abd2e6 in
order to fix undefined behavior from out-of-bounds reads when creating a GIF
with problematic LZW compression data.
Apply the changes from libgd/libgd@7ff626c48a in
order to fix undefined behavior when creating a GD2 image when a compressed
chunk claims to take `INT_MAX` space.
Headers required by the generated code (zend_attributes.h, zend_constants.h, zend_enum.h) are collected during generation and emitted as includes at the top of the arginfo file, with the same preprocessor conditions and PHP version guards as the code that needs them.
Removes the manual zend_attributes.h and zend_enum.h includes from sources that only needed them for the arginfo file they include.
php_imagettftext_common() serves the bbox functions, where $size is
argument #1, and the drawing ones, where it is #2, but its two size
checks hardcode 2. imageftbbox(NAN, ...) therefore blamed $angle.
Also fix the upper bound itself: (double)LONG_MAX rounds up to 2^63, so
(double)LONG_MAX / 64 is 2^57 and the check let 2^57 through, whose
product with 64 is LONG_MAX + 1. The bound is now exclusive, and the
reported values use integer division, which gives the largest size that
is actually representable. The lower bound stays inclusive:
(double)LONG_MIN / 64 is exactly -2^57 and its product with 64 is
LONG_MIN.
Co-authored-by: NickSdot <32384907+NickSdot@users.noreply.github.com>
Close GH-23541
imagebmp() writes its pixel data a byte at a time, and the gd stream
context turned each of those bytes into its own php_stream_write() call.
PHP streams do no write buffering, so a 1920x1080 truecolor image cost
about six million write syscalls. libgd's own FILE context does not show
this because stdio buffers for it.
Buffering the stream context in 8 KB chunks takes that image from 9.5s
to 0.02s here, with byte-identical output. imagewbmp(), imagegd() and
imagegd2() go through the same context and were writing per byte too, so
they get the same fix. imagexbm() goes through the same context but
writes its output via putBuf rather than per-byte putC, so it was not
affected by this bug and sees no change from this patch.
Close GH-23460
gdkanji.c includes <iconv.h> only when HAVE_ICONV_H or HAVE_ICONV is
set, but HAVE_ICONV_T_DEF was defined whenever <iconv.h> declares the
type, dropping its fallback typedef. Detect iconv in gd's own config
and define both macros together.
Runs the test suite in parallel by default; automatically selects up to 10 workers. Explicit -j1 remains the opt-out to run tests serial. Smaller batches improve balancing.
* Remove param argument from php_verror
Now that docref has been knocked out and error_include_args exists,
remove this argument. Callers will be updated accordingly.
* Remove param from exif
* Remove param from snmp (no changes for tests needed)
* Remove param from gd (no changes for tests needed)
* Remove param from openssl
* Document param change to php_verror
The gd 2.4 sync guarded gdkanji.c's 'typedef void *iconv_t' fallback
with HAVE_ICONV_T_DEF, which the bundled build never defined. On
Solaris <iconv.h> declares iconv_t as a struct pointer, so it clashed.
Define HAVE_ICONV_T_DEF when <iconv.h> already provides iconv_t.
1st part of syncing bundled LibGd to ext/gd/libgd
# Updated/Fixed
- Color Match improvement using Lab* + Delta-E and actual % as input
- Fix and improve freetype rendering and merge both php's libgd + libgd "new encoding"
- Fix RAMQ rendering
- All codecs with conformance tests (upstream, C)
- Perceptual difference (upstream C, will be exposed so php's tests can rely on it
- libgd codecs include gif, bmp, webp and jxl full support including animation. Tiff read/write multipages. all BMP format supported but OS/2.
Many of these additions or changes work already with existing php's apis.
2D vector APIs and all new Codecs or Gd\* APIs will be a separe PR+RFC. See https://wiki.php.net/rfc/ext-gd-2.4
imageloadfont_short_read packed the font header with pack('V4', ...)
(little-endian), but imageloadfont() reads the header as native-endian
ints. On big-endian hosts (PPC64 nightly) the byte-swapped values
overflow the INT_MAX guard before the FLIPWORD fallback runs, so the
font is rejected and the test fails. Pack the fields with 'i' to keep
the header valid regardless of host endianness.
Closes GH-22416
imageloadfont() read the font header with `(char*)&font[b]`, which scales
the byte counter b by sizeof(gdFont) rather than advancing one byte, so a
short php_stream_read() (deliverable by a user stream wrapper) makes the
loop write hdr_size-b bytes past the emalloc(sizeof(gdFont)) buffer. Index
the destination by bytes, matching the body read a few lines below.
Closes GH-22380
* ext/*: Make `X_from_obj(zend_object *obj)` functions macros
With the introduction of the `ZEND_CONTAINER_OF()` macro we can now preserve
whether or not the `zend_object *` is `const` when extracting the
class-specific struct. This change will allow to use `const zend_object *` in
more locations.
Changes performed with Coccinelle followed by some manual cleanup for comment
and whitespace formatting:
@a@
attribute name zend_always_inline;
type T;
identifier obj;
identifier f;
typedef zend_object;
@@
T* f(zend_object *obj) { return ZEND_CONTAINER_OF(obj, T, std); }
+ #define f(obj) ZEND_CONTAINER_OF(obj, T, std)
@@
identifier a.f;
@@
- f(...) { ... }
@b@
attribute name zend_always_inline;
type T;
identifier obj;
identifier f;
typedef zend_object;
@@
T* f(zend_object *obj) { return ZEND_CONTAINER_OF(obj, T, zo); }
+ #define f(obj) ZEND_CONTAINER_OF(obj, T, zo)
@@
identifier b.f;
@@
- f(...) { ... }
* sockets: Fix build
* odbc: Fix build
Port libgd f6202ec0de1c8340cf9b69c4a86c84fc63703207: validate the
computed bounding box in gdTransformAffineBoundingBox before casting
the floating-point coordinates to int, and propagate the failure
through gdTransformAffineGetImage.
close GH-22149