980 Commits
Author SHA1 Message Date
David Carlier 05d164f306 Merge branch 'PHP-8.6'
* PHP-8.6:
  Fix GH-24488: GC double-frees the SimpleXMLElement properties table
2026-10-22 13:27:22 +01:00
David Carlier e4576ef7a4 Merge branch 'PHP-8.5' into PHP-8.6
* PHP-8.5:
  Fix GH-24488: GC double-frees the SimpleXMLElement properties table
2026-10-22 13:27:21 +01:00
David Carlier 5bd92da0ab Merge branch 'PHP-8.4' into PHP-8.5
* PHP-8.4:
  Fix GH-24488: GC double-frees the SimpleXMLElement properties table
2026-10-22 13:27:20 +01:00
evanfordandClaude Opus 5.5 f963484725 Fix GH-24488: GC double-frees the SimpleXMLElement properties table
Since the GH-24050 fix, gc_collect_white() adds the table returned by
get_gc to the garbage buffer. sxe_object_free_storage() released
sxe->properties with zend_hash_release(), which does not remove the
table from the GC buffer, so the GC later read and freed it again.
Use zend_array_release(), which goes through zend_array_destroy().

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

Close GH-24494
2026-10-22 13:24:35 +01:00
Ilija Tovilo 9705fda1bb Merge branch 'PHP-8.6' into master
* PHP-8.6:
  Add NEWS entry
  Avoid state corruption via bailout
2026-10-21 16:34:56 +02:00
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
Ilia Alshanetsky 75204bee6f Fix GH-12171: resolve SimpleXML nodes before equality compare (#23187)
Property proxies like $xml->first store the parent node plus an element
iterator name. sxe_objects_compare compared the parent wrappers, so
sibling proxies always compared equal. Resolve each side through
php_sxe_get_first_node_non_destructive before comparing. When both sides
resolve to no node, keep comparing the parent wrappers, so two empty
results from the same parent still compare equal.

Fixes GH-12171
Closes GH-23187
2026-10-05 20:01:55 -04:00
Ilia Alshanetsky 65f7c719a3 Merge branch 'PHP-8.5' into PHP-8.6
* PHP-8.5:
  ext/libxml: Keep SimpleXML children alive across reconstruction
2026-09-29 14:53:12 -04:00
Ilia Alshanetsky e926c2a2ec Merge branch 'PHP-8.4' into PHP-8.5
* PHP-8.4:
  ext/libxml: Keep SimpleXML children alive across reconstruction
2026-09-29 14:16:24 -04:00
Ilia Alshanetsky efb8ad276d ext/libxml: Keep SimpleXML children alive across reconstruction
Reconstructing a SimpleXMLElement decremented the shared node and then
installed a new document while the old pointer was still set, so the
second decrement freed a node a child object still held. Clear the
pointer before the new node is installed.

Closes GH-23931
2026-09-29 14:06:21 -04:00
Ilia Alshanetsky 475811a186 Merge branch 'PHP-8.5'
* PHP-8.5:
  simplexml: fix addChild() namespace filter on the returned element
2026-09-08 06:26:50 -04:00
Ilia Alshanetsky cf65d03d60 Merge branch 'PHP-8.4' into PHP-8.5
* PHP-8.4:
  simplexml: fix addChild() namespace filter on the returned element
2026-09-08 06:25:33 -04:00
Ilia Alshanetsky 8b13fcc13e simplexml: fix addChild() namespace filter on the returned element
addChild() passed the caller's prefix to node_as_zval_str() with isprefix
set to 0, so the returned element filtered its children by comparing that
prefix against the namespace href and matched nothing. Take the prefix from
the created node and mark it as one, but only when the caller asked for a
namespace, so a plain addChild() keeps the unfiltered view that its
attributes and non-namespaced children rely on.

Closes GH-23599
2026-09-08 06:20:54 -04:00
Ilia Alshanetsky 860dda81f7 Merge branch 'PHP-8.5'
* PHP-8.5:
  [SimpleXML] Fix creating new attributes via attributes() dimension write
2026-08-30 11:05:13 -04:00
Ilia Alshanetsky 85417195b9 Merge branch 'PHP-8.4' into PHP-8.5
* PHP-8.4:
  [SimpleXML] Fix creating new attributes via attributes() dimension write
2026-08-30 11:04:27 -04:00
Ilia Alshanetsky fc7a6b9007 [SimpleXML] Fix creating new attributes via attributes() dimension write
sxe_prop_dim_write() overwrote the element node with the first attribute
node when resolving an SXE_ITER_ATTRLIST iterator, so xmlNewProp() targeted
a non-element node and was skipped entirely when no attribute existed yet.
Keep the element node in place and resolve only the attribute list start,
so $x->attributes()["new"] = "v" creates the attribute like the symmetric
$x["new"] path; property writes on the attributes() object share the fixed
path while read/exists/unset handlers are unaffected by this defect.

Closes GH-23500
2026-08-30 11:03:49 -04:00
NickSdot d9640d76c4 ext/simplexml: applied fixers to improve test robustness (#23030) 2026-08-22 14:03:08 +01:00
Ilia Alshanetsky 9d58ce53a1 Merge branch 'PHP-8.5'
* PHP-8.5:
  Fix segfault comparing uninitialized SimpleXMLElement instances
2026-08-10 10:23:54 -04:00
Ilia Alshanetsky 2806a3637e Merge branch 'PHP-8.4' into PHP-8.5
* PHP-8.4:
  Fix segfault comparing uninitialized SimpleXMLElement instances
2026-08-10 10:23:26 -04:00
Ilia Alshanetsky 7b1f5637b6 Fix segfault comparing uninitialized SimpleXMLElement instances
sxe_objects_compare dereferenced document->ptr when both nodes were
NULL without checking document. A subclass that skips parent
__construct leaves document NULL, so $a == $b segfaulted. Compare the
documents only when both are set; anything else is uncomparable.

Closes GH-23067
2026-08-10 10:06:49 -04:00
Ilia Alshanetsky bda5a4943e Reject NUL bytes in the SimpleXMLElement constructor (#23069)
With dataIsURL set the first argument goes to xmlReadFile as a C string,
so new SimpleXMLElement("/tmp/ok.xml\0evil", 0, true) truncates at the NUL
and quietly loads /tmp/ok.xml. simplexml_load_file() and
SimpleXMLElement::asXML() already declare their path argument as a path;
the constructor took a plain string, so the check never ran.

Closes GH-23069
2026-08-09 19:44:01 -04:00
Ilia Alshanetsky 4e55e35ead Merge branch 'PHP-8.5'
* PHP-8.5:
  Fix SimpleXML integer offsets that cannot resolve aliasing a node
2026-08-09 14:14:07 -04:00
Ilia Alshanetsky 4c955f4a2b Merge branch 'PHP-8.4' into PHP-8.5
* PHP-8.4:
  Fix SimpleXML integer offsets that cannot resolve aliasing a node
2026-08-09 14:13:43 -04:00
Ilia Alshanetsky 9e696413e8 Fix SimpleXML integer offsets that cannot resolve aliasing a node
sxe_get_element_by_offset scanned with nodendx <= offset, so a negative
offset skipped the loop and returned the node it started from, and the
SXE_ITER_NONE branches of the read and write handlers aliased the node
for every offset other than 0. Reads and isset() reported an existing
element and writes overwrote it. An offset that resolves to no element
now warns and leaves the document alone.

Closes GH-23068
2026-08-09 14:02:10 -04: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
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
Tim Düsterhus f1c6357363 Deprecate making __debugInfo() nullable (#21984)
* Deprecate making `__debugInfo()` nullable

Returning `null` is already deprecated since PHP 8.5
(3dc962b9f7). Not deprecating a corresponding
return type seems like an oversight.

* NEWS / UPGRADING
2026-05-16 18:20:07 +02: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
Ben Ramsey 85d1394380 license-update: ext/simplexml source headers
RFC: https://wiki.php.net/rfc/php_license_update
2026-04-11 21:20:54 -05:00
Alexandre Daubois a8543dfdd2 Convert remaining zend_parse_parameters_none() to ZPP (#21343) 2026-03-16 09:28:08 +01:00
Peter Kokot f17c5ad83b Windows build: Add new function CHECK_HEADER() (#21191)
The current function `CHECK_HEADER_ADD_INCLUDE()` automatically defines
`HAVE_<HEADER_NAME_H>` preprocessor macros, which makes it difficult to
sync with other build systems. Specially, if some `HAVE_` macro is used
in the code and this function defines this macro but Autotools doesn't.

The new `CHECK_HEADER()` function behaves similar except it doesn't
define the `HAVE_<HEADER_NAME_H>` preprocessor macro.

This removes the following unused compile definitions:

HAVE_ARGON2_H
HAVE_AVIF_H
HAVE_BZLIB_H
HAVE_CAPSTONE_CAPSTONE_H
HAVE_CURL_EASY_H
HAVE_DB_H
HAVE_DECODE_H
HAVE_DEPOT_H
HAVE_EDITLINE_READLINE_H
HAVE_ENCHANT_H
HAVE_ENCODE_H
HAVE_FFI_H
HAVE_FIREBIRD_INTERFACE_H
HAVE_FT2BUILD_H
HAVE_GD_H
HAVE_GLIB_H
HAVE_GMP_H
HAVE_HTTPD_H
HAVE_IBASE_H
HAVE_IR_IR_H
HAVE_KECCAKHASH_H
HAVE_LBER_H
HAVE_LDAP_H
HAVE_LIBEXSLT_EXSLT_H
HAVE_LIBINTL_H
HAVE_LIBPQ_FE_H
HAVE_LIBTIDY_TIDY_H
HAVE_LIBXML_PARSER_H
HAVE_LIBXML_TREE_H
HAVE_LIBXML_XMLWRITER_H
HAVE_LIBXSLT_XSLT_H
HAVE_LMDB_H
HAVE_MBSTRING_H
HAVE_MYSQL_H
HAVE_ONIGURUMA_H
HAVE_OPENSSL_SSL_H
HAVE_PNG_H
HAVE_SNMP_H
HAVE_SODIUM_H
HAVE_SQLITE3_H
HAVE_SQLITE3EXT_H
HAVE_SYBFRONT_H
HAVE_TIDY_H
HAVE_TIDY_TIDY_H
HAVE_TIDYBUFFIO_H
HAVE_TIMELIB_CONFIG_H
HAVE_UNICODE_USPOOF_H
HAVE_UNICODE_UTF_H
HAVE_XPM_H
HAVE_ZIP_H
HAVE_ZIPCONF_H
HAVE_ZLIB_H

The following compile definitions are defined explicitly:

- HAVE_ICONV_H
- HAVE_MSCOREE_H
- HAVE_SQL_H
- HAVE_SQLEXT_H

Additionally, the `SETUP_OPENSSL()` function doesn't accept the 6th
argument anymore.
2026-03-03 20:06:40 +01:00
Arnaud Le Blanc 65b4073922 Include the actual stub name in generated arginfo headers (#20993) 2026-01-21 20:57:00 +01:00
Niels Dossche 08ba240c81 simplexml: Avoid double lookups and unnecessary allocations in getNamespaces() (#20447) 2025-11-11 11:19:29 +01:00
Niels Dossche cff7d9eb6f Merge branch 'PHP-8.5'
* PHP-8.5:
  Partially fix GH-16317: SimpleXML does not allow __debugInfo() overrides to work
2025-10-12 11:25:46 +02:00
Niels Dossche 0b231c4895 Merge branch 'PHP-8.4' into PHP-8.5
* PHP-8.4:
  Partially fix GH-16317: SimpleXML does not allow __debugInfo() overrides to work
2025-10-12 11:25:31 +02:00
Niels Dossche aa1585f110 Merge branch 'PHP-8.3' into PHP-8.4
* PHP-8.3:
  Partially fix GH-16317: SimpleXML does not allow __debugInfo() overrides to work
2025-10-12 11:25:25 +02:00
Niels Dossche efa1fafc2f Partially fix GH-16317: SimpleXML does not allow __debugInfo() overrides to work
If only we did not have the pseudo-key "@attributes", we could've just
removed the custom get_debug_info implementation and this would work out
of the box. Anyway, we just have to manually check for an override now.

Closes GH-20131.
2025-10-12 11:24:45 +02:00
Niels Dossche 890021e2be SimpleXML: Use RETURN_STRINGL_FAST() for key() (#20127)
We do the same for getName() because names are often one char.
2025-10-11 10:46:33 +02:00
Niels Dossche 4db8993ee2 Merge branch 'PHP-8.5'
* PHP-8.5:
  Fix NEWS order
  Fix GH-19988: zend_string_init with NULL pointer in simplexml (UB)
2025-09-29 16:09:07 +02:00
Niels Dossche c1a6627417 Merge branch 'PHP-8.4' into PHP-8.5
* PHP-8.4:
  Fix NEWS order
  Fix GH-19988: zend_string_init with NULL pointer in simplexml (UB)
2025-09-29 16:08:56 +02:00
Niels Dossche 1bda46eb83 Merge branch 'PHP-8.3' into PHP-8.4
* PHP-8.3:
  Fix NEWS order
  Fix GH-19988: zend_string_init with NULL pointer in simplexml (UB)
2025-09-29 16:08:31 +02:00
Niels Dossche d94846c3b4 Fix GH-19988: zend_string_init with NULL pointer in simplexml (UB)
Normally, simplexml cannot import document nodes,
but xsl allows to circumvent this.
A document does not have a name, so we return the empty string
in that case.
While we could add an explicit check, we might as well switch
the macro to a form that would be more optimal anyway as many
tag names can be single characters.

The test was added in xsl because adding it in simplexml would
break out-of-tree builds of simplexml.

Closes GH-19990.
2025-09-29 16:07:34 +02:00
Tim Düsterhus 0583c66e2f simplexml: Use true / false instead of 1 / 0 when assigning to bool
Changes done with Coccinelle:

    @@
    bool b;
    @@

    - b = 0
    + b = false

    @@
    bool b;
    @@

    - b = 1
    + b = true
2025-09-24 18:51:40 +02:00
Niels Dossche 542712099f Merge branch 'PHP-8.4'
* PHP-8.4:
  Fix naming clash with libxml macro
2025-09-14 16:40:47 +02:00
Ruoyu Zhong 8774e96bd4 Fix naming clash with libxml macro
In the macOS 26 SDK, xmlFree is defined as a macro for free. This causes
issues where a same-named variable is used. Renaming the variable to
should_free resolves the issue.

See:

    $ grep -B4 -A2 -n "#define xmlFree(" "Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX26.sdk/usr/include/libxml/globals.h"
    261-#if defined(LIBXML_HAS_DEPRECATED_MEMORY_ALLOCATION_FUNCTIONS)
    262-#define xmlMalloc(size) malloc(size)
    263-#define xmlMallocAtomic(size) malloc(size)
    264-#define xmlRealloc(ptr, size) realloc((ptr), (size))
    265:#define xmlFree(ptr) free(ptr)
    266-#define xmlMemStrdup(str) strdup(str)
    267-#endif

Fixes:
```
    In file included from /Library/Developer/CommandLineTools/SDKs/MacOSX26.sdk/usr/include/libxml/xmlIO.h:117,
                    from /Library/Developer/CommandLineTools/SDKs/MacOSX26.sdk/usr/include/libxml/parser.h:813,
                    from /private/tmp/php-20250914-13349-uqsk5o/php-8.4.12/ext/dom/php_dom.h:29,
                    from /private/tmp/php-20250914-13349-uqsk5o/php-8.4.12/ext/dom/attr.c:26:
    /private/tmp/php-20250914-13349-uqsk5o/php-8.4.12/ext/dom/attr.c: In function 'dom_compare_value':
    /private/tmp/php-20250914-13349-uqsk5o/php-8.4.12/ext/dom/attr.c:208:17: error: called object 'free' is not a function or function pointer
      208 |                 xmlFree(attr_value);
          |                 ^~~~~~~
    /private/tmp/php-20250914-13349-uqsk5o/php-8.4.12/ext/dom/attr.c:204:14: note: declared here
      204 |         bool free;
          |              ^~~~
    make: *** [ext/dom/attr.lo] Error 1
```

Closes GH-19832.

Signed-off-by: Ruoyu Zhong <zhongruoyu@outlook.com>
2025-09-14 16:40:22 +02:00
Gina Peter Banyard 05eda4318d Add missing extension dependencies for tests 2025-09-11 15:10:49 +02:00