945 Commits
Author SHA1 Message Date
Shivam Mathur 9e769f0a41 Merge branch 'PHP-8.5' into PHP-8.6
* PHP-8.5:
  Fix GH-24533: Accept z.lib from zlib 1.3.2 CMake builds on Windows (#24539)
2026-10-22 22:19:51 +05:30
Shivam Mathur 9080c462d5 Merge branch 'PHP-8.4' into PHP-8.5
* PHP-8.4:
  Fix GH-24533: Accept z.lib from zlib 1.3.2 CMake builds on Windows (#24539)
2026-10-22 22:18:26 +05:30
Lazizbek Ergashev 3d3d3665a7 Fix GH-24533: Accept z.lib from zlib 1.3.2 CMake builds on Windows (#24539)
* Fix GH-24533: Accept z.lib from zlib 1.3.2 CMake builds on Windows

* Prefer static zs.lib and add NEWS entry

* Accept zlib 1.3.2 lib names in the other zlib lookups
2026-10-22 22:14:05 +05:30
Ilija Tovilo d6373dfe15 Merge branch 'PHP-8.5' into PHP-8.6
* PHP-8.5:
  Add NEWS entry
  Avoid state corruption via bailout
2026-10-21 16:33:23 +02:00
Ilija Tovilo c7273b9ba8 Merge branch 'PHP-8.4' into PHP-8.5
* PHP-8.4:
  Add NEWS entry
  Avoid state corruption via bailout
2026-10-21 16:30:04 +02:00
Ilija Tovilo 8a94bb3822 Merge branch 'PHP-8.3' into PHP-8.4
* PHP-8.3:
  Add NEWS entry
  Avoid state corruption via bailout
2026-10-21 16:27:03 +02:00
Ilija Tovilo c1a5f468d0 Merge branch 'PHP-8.2' into PHP-8.3
* PHP-8.2:
  Add NEWS entry
  Avoid state corruption via bailout
2026-10-21 16:12:35 +02:00
3584a98bda Avoid state corruption via bailout
- 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>
2026-10-21 16:06:22 +02:00
Weilin Du 70e083cb05 Merge branch 'PHP-8.5' into PHP-8.6
* PHP-8.5:
  Fix use-after-free when removing a failing zlib.inflate filter (#24176)
2026-10-10 03:47:08 +08:00
Weilin Du 4cf3ed94a8 Merge branch 'PHP-8.4' into PHP-8.5
* PHP-8.4:
  Fix use-after-free when removing a failing zlib.inflate filter (#24176)
2026-10-10 03:46:30 +08:00
Edmond d5f84c738b Fix use-after-free when removing a failing zlib.inflate filter (#24176)
Corrupt input makes zlib.inflate raise an E_NOTICE. An error handler can
remove the filter and free its state, so resetting the input pointers after
the notice writes to freed memory.

Release the input bucket and reset the filter state before raising the
notice, then return without accessing the filter again. Add regression
coverage for error handlers that remove both write and read filters.

Closing the stream itself from an error handler is outside this fix and
requires protection around the filter chain walk.

Closes #24176
2026-10-10 03:45:59 +08:00
Ilia Alshanetsky fb76b3d715 ext/zlib: honor preset dictionary for raw inflate with non-default window
inflate_init() applies the preset dictionary eagerly for raw streams via
inflateSetDictionary(), gated on encoding == PHP_ZLIB_ENCODING_RAW. But
encoding is first adjusted by the window size (encoding += 15 - window),
so a raw stream with a non-default window no longer equals
PHP_ZLIB_ENCODING_RAW and the dictionary is silently dropped; raw streams
carry no header and never emit Z_NEED_DICT, so inflate_add()'s deferred
path never applies it either. Gate on the pre-adjustment encoding. The
deflate side already applies the dictionary unconditionally, so the
roundtrip was broken for this case.

Closes GH-22381
2026-09-19 18:02:39 -04:00
Ilia Alshanetsky 64760a1eda Merge branch 'PHP-8.5'
* PHP-8.5:
  ext/zlib: honor preset dictionary for raw inflate with non-default window
2026-09-19 18:02:39 -04:00
Dmytro Kulyk 67135cb97b gen_stub: Conditionally include zend_attributes.h to arginfo based on usage (#21570)
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.
2026-09-06 21:25:20 +02:00
Gina Peter Banyard 148932c848 ext/zlib: pack php_zlib_filter_data struct
Reduces size from 160 to 152 bytes
2026-09-06 14:38:34 +01:00
David Carlier c0e7d498c5 ext/zlib: deflate_init() assertion failure on uninitialised typed properties
Fix GH-22142

An object passed as options exposes uninitialised typed properties as
IS_UNDEF slots, which zval_try_get_long() rejected through an unreachable
branch. Those slots are now skipped, matching get_object_vars().

Close GH-23409
2026-08-22 15:41:56 +01:00
David Carlier 7a8131e09c Revert "Fix GH-22142: Assertion failure in zendi_try_get_long() on IS_UNDEF."
This reverts commit 9e1b285f65.
2026-08-22 13:54:52 +01:00
Gina Peter Banyard 148afdb60a zlib: use new stream error API 2026-08-10 19:23:47 +01:00
Gina Peter Banyard 1cf82bef0a zlib: Add test with invalid levels 2026-08-10 19:23:47 +01:00
Gina Peter Banyard f8c854e82f zlib: deprecate passing objects as array
Implements RFCs:
- https://wiki.php.net/rfc/deprecations_php_8_6#passing_objects_for_options_parameter_of_deflate_init_and_inflate_init
- https://wiki.php.net/rfc/deprecations_php_8_6#passing_objects_as_parameters_to_the_zlibinflate_and_zlibdeflate_stream_filters
2026-08-10 18:21:19 +01:00
NickSdot 1d2ea5ce22 Run tests in parallel by default (#22939)
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.
2026-08-10 11:33:43 +02:00
Gina Peter Banyard 9675080b10 tests: remove unnecessary ZPP tests (#23020) 2026-08-04 21:03:44 +01:00
NickSdot 1da3a6398b Applied fixers to improve test robustness to extensions with no code owners (#23018)
* ext/bz2: applied fixers to improve test robustness

* ext/calendar: applied fixers to improve test robustness

* ext/exif: applied fixers to improve test robustness

* ext/fileinfo: applied fixers to improve test robustness

* ext/filter: applied fixers to improve test robustness

* ext/ftp: applied fixers to improve test robustness

* ext/hash: applied fixers to improve test robustness

* ext/iconv: applied fixers to improve test robustness

* ext/ldap: applied fixers to improve test robustness

* ext/pcre: applied fixers to improve test robustness

* ext/posix: applied fixers to improve test robustness

* ext/readline: applied fixers to improve test robustness

* ext/shmop: applied fixers to improve test robustness

* ext/snmp: applied fixers to improve test robustness

* ext/sodium: applied fixers to improve test robustness

* ext/sqlite3: applied fixers to improve test robustness

* ext/sysvmsg: applied fixers to improve test robustness

* ext/sysvsem: applied fixers to improve test robustness

* ext/sysvshm: applied fixers to improve test robustness

* ext/tidy: applied fixers to improve test robustness

* ext/tokenizer: applied fixers to improve test robustness

* ext/zend_test: applied fixers to improve test robustness

* ext/zlib: applied fixers to improve test robustness
2026-08-04 13:10:07 +01:00
Gina Peter Banyard 34c686a5b4 stream: remove path parameter in stream error functions (#22792)
Instead rely on the mechanism gated by the error_include_args INI to display them.

This actually aligns the behaviour of what was accepted in https://wiki.php.net/rfc/display_error_function_args.
2026-07-19 16:15:01 +01:00
Gina Peter Banyard 1f7abed789 streams: remove php_stream_wrapper_warn_param() functions
And instead let the normal docref error handling code handle arguments
2026-07-17 14:33:38 +01:00
ndossche ad1cf51972 Merge branch 'PHP-8.5'
* PHP-8.5:
  zlib: Fix memory leak in inflate_add()
  zlib: no need to free dict on inflate init error
2026-06-07 10:58:17 +02:00
ndossche 081487078c Merge branch 'PHP-8.4' into PHP-8.5
* PHP-8.4:
  zlib: Fix memory leak in inflate_add()
  zlib: no need to free dict on inflate init error
2026-06-07 10:58:09 +02:00
ndossche 73d9145ef5 zlib: Fix memory leak in inflate_add()
Closes GH-22239.
2026-06-07 10:57:41 +02:00
ndossche 98a644c02d zlib: no need to free dict on inflate init error
This was introduced in b0ef5fcaa1 because
it added `efree(dict)` to both inflate and deflate error handling.
But this is only necessary for the deflate case, not the inflate case
(as also shown in the original leak report).
2026-06-07 10:57:00 +02:00
Tim Düsterhus 69e023fd84 ext/*: Make X_from_obj(zend_object *obj) functions macros (#22183)
* 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
2026-06-01 10:21:03 +02:00
David Carlier 9e1b285f65 Fix GH-22142: Assertion failure in zendi_try_get_long() on IS_UNDEF.
close GH-22143
2026-05-25 19:12:29 +01:00
ndossche 5fd337e636 Merge branch 'PHP-8.5'
* PHP-8.5:
  zlib: fix test skipif sections (#22099)
2026-05-24 19:40:03 +02:00
ndossche daa9b09d56 Merge branch 'PHP-8.4' into PHP-8.5
* PHP-8.4:
  zlib: fix test skipif sections (#22099)
2026-05-24 19:39:49 +02:00
Nora Dossche 7727193818 zlib: fix test skipif sections (#22099)
Depending on the specific PHP configuration, the regex matching for the
version number in get_zlib_version() can fail.
On master, this results in deprecation warnings and subsequent test
borks:
```
Deprecated: version_compare(): Passing null to parameter #1 ($version1) of type string is deprecated in /work/php-src/ext/zlib/tests/gzgetc_basic.skip.php on line 3 [/work/php-src/ext/zlib/tests/gzgetc_basic.phpt]
Deprecated: version_compare(): Passing null to parameter #1 ($version1) of type string is deprecated in /work/php-src/ext/zlib/tests/gzgetc_basic_1.skip.php on line 4
```

Since ZLIB_VERSION is a constant containing the version as a string,
remove all this nonsense and just use the constant directly.
2026-05-24 19:37:34 +02:00
ndossche a544b8b1dd Merge branch 'PHP-8.5'
* PHP-8.5:
  zlib: fix memory leak if deflate initialization fails and there is a dict
2026-05-22 19:44:17 +02:00
ndossche ba9dfa733f Merge branch 'PHP-8.4' into PHP-8.5
* PHP-8.4:
  zlib: fix memory leak if deflate initialization fails and there is a dict
2026-05-22 19:44:11 +02:00
ndossche b0ef5fcaa1 zlib: fix memory leak if deflate initialization fails and there is a dict
```
Direct leak of 52 byte(s) in 1 object(s) allocated from:
    #0 0x7ff90cd2c161 in malloc (/usr/lib/libasan.so.8+0x12c161) (BuildId: ee5fbab73143ab257a66a33afe0f038a4af7a74e)
    #1 0x55de10c9a468 in tracked_malloc /work/php-8.4/Zend/zend_alloc.c:2973
    #2 0x55de10c99443 in _emalloc /work/php-8.4/Zend/zend_alloc.c:2740
    #3 0x55de102deb86 in zlib_create_dictionary_string /work/php-8.4/ext/zlib/zlib.c:836
    #4 0x55de102e145a in zif_deflate_init /work/php-8.4/ext/zlib/zlib.c:1144
    #5 0x55de10dcac6c in ZEND_DO_ICALL_SPEC_RETVAL_USED_HANDLER /work/php-8.4/Zend/zend_vm_execute.h:1351
    #6 0x55de10f2d69d in execute_ex /work/php-8.4/Zend/zend_vm_execute.h:58907
    #7 0x55de10f41666 in zend_execute /work/php-8.4/Zend/zend_vm_execute.h:64334
    #8 0x55de110a6cf8 in zend_execute_script /work/php-8.4/Zend/zend.c:1934
    #9 0x55de10af0ddb in php_execute_script_ex /work/php-8.4/main/main.c:2577
    #10 0x55de10af128f in php_execute_script /work/php-8.4/main/main.c:2617
    #11 0x55de110ac5e1 in do_cli /work/php-8.4/sapi/cli/php_cli.c:935
    #12 0x55de110ae592 in main /work/php-8.4/sapi/cli/php_cli.c:1322
    #13 0x7ff90c027740  (/usr/lib/libc.so.6+0x27740) (BuildId: 020d6f7c33b2413f4fe10814c4729dce1387f049)
    #14 0x7ff90c027878 in __libc_start_main (/usr/lib/libc.so.6+0x27878) (BuildId: 020d6f7c33b2413f4fe10814c4729dce1387f049)
    #15 0x55de10005964 in _start (/work/php-8.4/sapi/cli/php+0x605964) (BuildId: 5f144db4e56ea623e070c56445fb1dfa3f8d085d)

SUMMARY: AddressSanitizer: 52 byte(s) leaked in 1 allocation(s).
```

Closes GH-22101.
2026-05-22 19:43:44 +02:00
Tim Düsterhus ad7cce6527 zend_portability: Add ZEND_CONTAINER_OF() (#21903)
* zend_portability: Add `ZEND_CONTAINER_OF()`

* tree-wide: Use `ZEND_CONTAINER_OF()`

Changes made with Coccinelle:

    @@
    type T_container;
    identifier member;
    expression e;
    @@

    - (T_container *)(((char *)(e)) - offsetof(T_container, member))
    + ZEND_CONTAINER_OF(e, T_container, member)

    @@
    type T_container;
    identifier member;
    expression e;
    typedef uintptr_t;
    @@

    - (T_container *)(((uintptr_t)(e)) - offsetof(T_container, member))
    + ZEND_CONTAINER_OF(e, T_container, member)

    @@
    type T_container;
    identifier member;
    expression e;
    @@

    - (const T_container *)(((char *)(e)) - offsetof(T_container, member))
    + ZEND_CONTAINER_OF(e, T_container, member)

    @@
    type T_container;
    identifier member;
    expression e;
    typedef uintptr_t;
    @@

    - (const T_container *)(((uintptr_t)(e)) - offsetof(T_container, member))
    + ZEND_CONTAINER_OF(e, T_container, member)

* bcmath: Fix `get_bcmath_number_from_obj()` const-correctness

A follow-up change to the new `ZEND_CONTAINER_OF()` macro will preserve the
`const`-ness of the input pointer. By wrapping this macro inside a macro rather
an an inline function we can preserve the `const`-ness across all layers.

* zend_portability: Keep `const`-ness in `ZEND_CONTAINER_OF()`

* zend_portability: Add C++ version to `ZEND_CONTAINER_OF()`
2026-05-19 10:47:00 +02:00
Jakub Zelenka b114db0ddc streams: split filter seekability into read and write fields (#21878)
The single seekable field caused write-chain seeks to reset filter
state after the bug #49874 fix, breaking dechunk on php://temp (used
by Symfony HttpClient).

Split into read_seekable and write_seekable. Write defaults to ALWAYS
for stateless and non-buffering filters. Buffer-holding filters
(zlib, bz2, convert.*) accept a write_seek_mode parameter:
"preserve" (default), "reset", or "strict". Invalid values throw
ValueError.

php_user_filter::seek gains a third int $chain argument; the ops
seek signature is unchanged.
2026-05-11 20:12:08 +02:00
Weilin Du 7a3d889ad8 ext/zlib: Remove zval_get_long usage in inflate_init() (#21909)
This is a follow-up on the removal of the silent casts in deflate_init().
2026-04-30 14:41:39 +01:00
Weilin DuandGina Peter Banyard 70f0ca5f19 Zlib: Improve type checking of several integer options in deflate_init() (#21860)
`zval_get_long()` does a forceful cast and will even cast values like arrays or objects into integers, something that points to a bug. Use the more modern `zval_try_get_long()` API instead.

Create a helper function to handle the options consistently.

Co-authored-by: Gina Peter Banyard <girgias@php.net>
2026-04-29 07:45:45 +01:00
Tim Düsterhus 7114314c5a tree-wide: Replace XtOffsetOf by its definition (#21899)
`offsetof()` is in `stddef.h` and thus always available. The extra macro is an
unnecessary layer of indirection.
2026-04-28 22:12:56 +02:00
Weilin Du c23efeb5c4 Zlib: Fix the bug when zval_get_long silently cast $strategy into long in deflate_init (#21841) 2026-04-23 17:35:49 +01:00
Ben Ramsey 40be849858 license-update: ext/zlib source headers
RFC: https://wiki.php.net/rfc/php_license_update
2026-04-11 21:20:54 -05:00
Tim Düsterhus 04f06e8cf2 zend_portability: Remove EMPTY_SWITCH_DEFAULT_CASE() (#20063)
There are several issues with this macro:

- It is incorrectly named: It's not an empty default case. It's an unreachable
  default case.
- It is hiding control flow in its definition, which can be confusing for
  humans and tools (such as Coccinelle) alike, because it looks like it would
  be a statement that belongs to the "current" case rather than opening a new
  one.

Since this macro is exactly as long as explicitly spelling out its definition
(excluding the useless `break;`), it is not even making the code any more
succinct.
2026-04-06 14:46:15 +02:00
Gina Peter Banyard cd753007ce Audit INI functions and macros, and replace them with better alternatives (#21146)
Audit zend_ini_string(), INI_STR(), and related functions and macros, and all other INI_* macros.

The primary motivation is that these APIs should return a `const char*` because the `char*` is owned by a zend_string, and thus should never be released.

Moreover, the INI_STR() API doesn't follow our usual naming scheme as it returns a char* rather than a zend_string*.

In this PR new zend_ini_{bool|long|double|str|string}_literal() macros are introduced replacing the INI_{BOOL|INT|FLT|STR} macros which follow our more modern naming convention.
Moreover, the INI_BOOL() macro didn't produce correct values if the INI string is a word like "true" or "on".

The INI_ORIG_* APIs are removed because a Sourcegraph search shows 0 results, other than the one case used in ext/tidy that we fix using the typical API.

Add some additional checks for the value of an INI string to ensure it doesn't contain a nul byte when describing a path.
2026-03-30 14:48:12 +01:00
Jakub Zelenka 358d9c54a6 Fix bug #49874: ftell() and fseek() inconsistency when using stream filters (#19981)
Currently filter seeking does not work correctly for most streams. The
idea is to extend API to allow seeking for some streams. There are
couple of cases:

- filter is always seekable - e.g. string.rot13, string.toupper,
  string.tolower
- filter is seekable only when sought to start or when it re-run the
  data from the start (it means when there is some data buffered) -
  this is for pretty much all other filters that keep some state.
- user filters are seekable by default for BC reason but if new
  seek method is implemented, then it is called and based on the
  bool result the seeking either fails or succeed.
2026-03-30 10:27:34 +02:00
Weilin Du 2918caee20 ext/*: Remove break after return (#21485) 2026-03-23 20:30:13 +01:00
Alexandre Daubois 11a95749b1 Convert more zend_parse_parameters_none() to fast ZPP (#21330) 2026-03-04 14:07:46 +01:00
Petr Sumbera ce1cadba29 Fix Solaris tests and add nightly CI job
Closes GH-20709
2026-03-04 10:12:03 +01:00