From 4a6e6077ef1ba1cd2b94c0f4af7e342393043538 Mon Sep 17 00:00:00 2001 From: Alexandre Daubois <2144837+alexandre-daubois@users.noreply.github.com> Date: Fri, 30 Jan 2026 16:18:33 +0100 Subject: [PATCH 1/4] Core: fix missing deprecation when accessing null array key with JIT (#20883) --- NEWS | 2 ++ Zend/Optimizer/sccp.c | 3 +-- ext/opcache/tests/jit/fetch_dim_r_001.phpt | 4 +++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index 07c66ec833e0f..c6bedf8ed114f 100644 --- a/NEWS +++ b/NEWS @@ -7,6 +7,8 @@ PHP NEWS . Fixed bug GH-21059 (Segfault when preloading constant AST closure). (ilutov) . Fixed bug GH-21072 (Crash on (unset) cast in constant expression). (arshidkv12) + . Fix deprecation now showing when accessing null key of an array with JIT. + (alexandre-daubois) - Windows: . Fixed compilation with clang (missing intrin.h include). (Kévin Dunglas) diff --git a/Zend/Optimizer/sccp.c b/Zend/Optimizer/sccp.c index 7e2fc2db1b256..87d7507d4f9a4 100644 --- a/Zend/Optimizer/sccp.c +++ b/Zend/Optimizer/sccp.c @@ -363,8 +363,7 @@ static inline zend_result zval_to_string_offset(zend_long *result, zval *op) { static inline zend_result fetch_array_elem(zval **result, zval *op1, zval *op2) { switch (Z_TYPE_P(op2)) { case IS_NULL: - *result = zend_hash_find(Z_ARR_P(op1), ZSTR_EMPTY_ALLOC()); - return SUCCESS; + return FAILURE; case IS_FALSE: *result = zend_hash_index_find(Z_ARR_P(op1), 0); return SUCCESS; diff --git a/ext/opcache/tests/jit/fetch_dim_r_001.phpt b/ext/opcache/tests/jit/fetch_dim_r_001.phpt index 3ff56263db683..819ec7edca655 100644 --- a/ext/opcache/tests/jit/fetch_dim_r_001.phpt +++ b/ext/opcache/tests/jit/fetch_dim_r_001.phpt @@ -30,7 +30,7 @@ function foo() { } foo(); ?> ---EXPECT-- +--EXPECTF-- int(1) int(3) int(2) @@ -38,6 +38,8 @@ int(1) int(3) int(1) int(2) + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d int(4) int(5) int(5) From d03d69a88a3f8dd4772833fc81b293750eb7b482 Mon Sep 17 00:00:00 2001 From: Khaled Alam Date: Fri, 30 Jan 2026 19:37:13 +0400 Subject: [PATCH 2/4] Remove duplicate #include statements (#21085) * Remove duplicate #include statements across the codebase. * feat: Restore conditional/unconditional include pairs in lscriu.c --- Zend/Optimizer/zend_call_graph.c | 2 -- Zend/Optimizer/zend_func_info.c | 1 - Zend/zend_compile.h | 6 ------ ext/libxml/libxml.c | 1 - ext/mysqli/mysqli.c | 1 - ext/phar/phar_object.c | 1 - ext/standard/basic_functions.c | 1 - ext/standard/ftp_fopen_wrapper.c | 1 - ext/standard/http_fopen_wrapper.c | 1 - main/fopen_wrappers.c | 1 - main/main.c | 2 -- sapi/apache2handler/apache_config.c | 1 - sapi/apache2handler/php_functions.c | 1 - sapi/apache2handler/sapi_apache2.c | 1 - sapi/cgi/cgi_main.c | 1 - sapi/cli/php_cli.c | 2 -- sapi/cli/php_cli_server.c | 1 - sapi/fpm/fpm/fpm_conf.c | 1 - sapi/fpm/fpm/fpm_main.c | 3 --- sapi/litespeed/lscriu.c | 1 - sapi/phpdbg/phpdbg_parser.y | 1 - 21 files changed, 31 deletions(-) diff --git a/Zend/Optimizer/zend_call_graph.c b/Zend/Optimizer/zend_call_graph.c index 645edd2f99914..884b481aceb8e 100644 --- a/Zend/Optimizer/zend_call_graph.c +++ b/Zend/Optimizer/zend_call_graph.c @@ -23,8 +23,6 @@ #include "zend_inference.h" #include "zend_call_graph.h" #include "zend_func_info.h" -#include "zend_inference.h" -#include "zend_call_graph.h" static void zend_op_array_calc(zend_op_array *op_array, void *context) { diff --git a/Zend/Optimizer/zend_func_info.c b/Zend/Optimizer/zend_func_info.c index f3b0d663dd6df..cec52f7e98602 100644 --- a/Zend/Optimizer/zend_func_info.c +++ b/Zend/Optimizer/zend_func_info.c @@ -24,7 +24,6 @@ #include "zend_inference.h" #include "zend_call_graph.h" #include "zend_func_info.h" -#include "zend_inference.h" #ifdef _WIN32 #include "win32/ioutil.h" #endif diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index 6075ae3d1e5d2..006a89597aedd 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -1031,12 +1031,6 @@ void zend_assert_valid_class_name(const zend_string *const_name, const char *typ zend_string *zend_type_to_string_resolved(zend_type type, zend_class_entry *scope); ZEND_API zend_string *zend_type_to_string(zend_type type); -/* BEGIN: OPCODES */ - -#include "zend_vm_opcodes.h" - -/* END: OPCODES */ - /* class fetches */ #define ZEND_FETCH_CLASS_DEFAULT 0 #define ZEND_FETCH_CLASS_SELF 1 diff --git a/ext/libxml/libxml.c b/ext/libxml/libxml.c index 0105106d9531b..5a0e1f3c7a096 100644 --- a/ext/libxml/libxml.c +++ b/ext/libxml/libxml.c @@ -35,7 +35,6 @@ #include #include #include -#include #include #ifdef LIBXML_SCHEMAS_ENABLED #include diff --git a/ext/mysqli/mysqli.c b/ext/mysqli/mysqli.c index 26264aa2b170f..b171986d29cef 100644 --- a/ext/mysqli/mysqli.c +++ b/ext/mysqli/mysqli.c @@ -32,7 +32,6 @@ #include "zend_exceptions.h" #include "ext/spl/spl_exceptions.h" #include "zend_interfaces.h" -#include "zend_attributes.h" #include "mysqli_arginfo.h" ZEND_DECLARE_MODULE_GLOBALS(mysqli) diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c index 5dd1dc4090cd5..2d8ee9c435ed8 100644 --- a/ext/phar/phar_object.c +++ b/ext/phar/phar_object.c @@ -27,7 +27,6 @@ #include "main/SAPI.h" #include "zend_exceptions.h" #include "zend_interfaces.h" -#include "zend_exceptions.h" static zend_class_entry *phar_ce_archive; static zend_class_entry *phar_ce_data; diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index 1d7f2c1a9b59d..d96de3947d5d2 100644 --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@ -102,7 +102,6 @@ typedef struct yy_buffer_state *YY_BUFFER_STATE; #endif #include "zend_globals.h" -#include "php_globals.h" #include "SAPI.h" #include "php_ticks.h" diff --git a/ext/standard/ftp_fopen_wrapper.c b/ext/standard/ftp_fopen_wrapper.c index d1bb3aeeccd68..92200e64f2384 100644 --- a/ext/standard/ftp_fopen_wrapper.c +++ b/ext/standard/ftp_fopen_wrapper.c @@ -41,7 +41,6 @@ #include "php_standard.h" #include "ext/uri/php_uri.h" -#include #ifdef HAVE_SYS_SOCKET_H #include #endif diff --git a/ext/standard/http_fopen_wrapper.c b/ext/standard/http_fopen_wrapper.c index da150381f43f3..b5c06b84a6aa4 100644 --- a/ext/standard/http_fopen_wrapper.c +++ b/ext/standard/http_fopen_wrapper.c @@ -44,7 +44,6 @@ #include "php_standard.h" -#include #ifdef HAVE_SYS_SOCKET_H #include #endif diff --git a/main/fopen_wrappers.c b/main/fopen_wrappers.c index 63564cc73bdfc..f1ab7312c46ee 100644 --- a/main/fopen_wrappers.c +++ b/main/fopen_wrappers.c @@ -44,7 +44,6 @@ #include #endif -#include #ifdef HAVE_SYS_SOCKET_H #include #endif diff --git a/main/main.c b/main/main.c index 446ac0fcb7970..afb9291586de2 100644 --- a/main/main.c +++ b/main/main.c @@ -64,7 +64,6 @@ #include "win32/php_registry.h" #include "ext/standard/flock_compat.h" #endif -#include "php_syslog.h" #include "Zend/zend_exceptions.h" #if PHP_SIGCHILD @@ -75,7 +74,6 @@ #include "zend_compile.h" #include "zend_execute.h" #include "zend_highlight.h" -#include "zend_extensions.h" #include "zend_ini.h" #include "zend_dtrace.h" #include "zend_observer.h" diff --git a/sapi/apache2handler/apache_config.c b/sapi/apache2handler/apache_config.c index e051964a81591..a31ba68f92815 100644 --- a/sapi/apache2handler/apache_config.c +++ b/sapi/apache2handler/apache_config.c @@ -37,7 +37,6 @@ #include "http_log.h" #include "http_main.h" #include "util_script.h" -#include "http_core.h" #ifdef PHP_AP_DEBUG #define phpapdebug(a) fprintf a diff --git a/sapi/apache2handler/php_functions.c b/sapi/apache2handler/php_functions.c index 84437f12ebe9f..9b073207c8198 100644 --- a/sapi/apache2handler/php_functions.c +++ b/sapi/apache2handler/php_functions.c @@ -41,7 +41,6 @@ #include "http_log.h" #include "http_main.h" #include "util_script.h" -#include "http_core.h" #include "ap_mpm.h" #ifndef PHP_WIN32 #include "unixd.h" diff --git a/sapi/apache2handler/sapi_apache2.c b/sapi/apache2handler/sapi_apache2.c index 88fc584a8bcbb..2387d24741a4b 100644 --- a/sapi/apache2handler/sapi_apache2.c +++ b/sapi/apache2handler/sapi_apache2.c @@ -46,7 +46,6 @@ #include "http_log.h" #include "http_main.h" #include "util_script.h" -#include "http_core.h" #include "ap_mpm.h" #include "php_apache.h" diff --git a/sapi/cgi/cgi_main.c b/sapi/cgi/cgi_main.c index 6db96a43ac97b..3decc673389b3 100644 --- a/sapi/cgi/cgi_main.c +++ b/sapi/cgi/cgi_main.c @@ -59,7 +59,6 @@ #include "zend.h" #include "zend_extensions.h" #include "php_ini.h" -#include "php_globals.h" #include "php_main.h" #include "fopen_wrappers.h" #include "http_status_codes.h" diff --git a/sapi/cli/php_cli.c b/sapi/cli/php_cli.c index 460acb62664a6..d1781eab671c9 100644 --- a/sapi/cli/php_cli.c +++ b/sapi/cli/php_cli.c @@ -31,7 +31,6 @@ #include "SAPI.h" #include -#include "php.h" #ifdef PHP_WIN32 #include "win32/time.h" #include "win32/signal.h" @@ -51,7 +50,6 @@ #include "zend.h" #include "zend_extensions.h" #include "php_ini.h" -#include "php_globals.h" #include "php_main.h" #include "fopen_wrappers.h" #include "ext/standard/php_standard.h" diff --git a/sapi/cli/php_cli_server.c b/sapi/cli/php_cli_server.c index 046e2174dc1d8..bab7ad011e07d 100644 --- a/sapi/cli/php_cli_server.c +++ b/sapi/cli/php_cli_server.c @@ -44,7 +44,6 @@ #include #endif -#include #include #ifdef HAVE_DLFCN_H diff --git a/sapi/fpm/fpm/fpm_conf.c b/sapi/fpm/fpm/fpm_conf.c index 63f911af490c7..3979d875a18e5 100644 --- a/sapi/fpm/fpm/fpm_conf.c +++ b/sapi/fpm/fpm/fpm_conf.c @@ -8,7 +8,6 @@ #include #include #include -#include #include #include diff --git a/sapi/fpm/fpm/fpm_main.c b/sapi/fpm/fpm/fpm_main.c index cc89b8c07c155..f1f7de70b279b 100644 --- a/sapi/fpm/fpm/fpm_main.c +++ b/sapi/fpm/fpm/fpm_main.c @@ -24,7 +24,6 @@ #include "php_variables.h" #include "php_ini_builder.h" #include "zend_modules.h" -#include "php.h" #include "zend_ini_scanner.h" #include "zend_globals.h" #include "zend_stream.h" @@ -32,7 +31,6 @@ #include "SAPI.h" #include -#include "php.h" #ifdef HAVE_SYS_TIME_H # include @@ -61,7 +59,6 @@ #include "zend.h" #include "zend_extensions.h" #include "php_ini.h" -#include "php_globals.h" #include "php_main.h" #include "fopen_wrappers.h" #include "ext/standard/php_standard.h" diff --git a/sapi/litespeed/lscriu.c b/sapi/litespeed/lscriu.c index 042f5fb7a2b5c..9d4096ec1c317 100644 --- a/sapi/litespeed/lscriu.c +++ b/sapi/litespeed/lscriu.c @@ -73,7 +73,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include #include -#include #include #include #include diff --git a/sapi/phpdbg/phpdbg_parser.y b/sapi/phpdbg/phpdbg_parser.y index 50cb93f05f6f0..eb711632eb59a 100644 --- a/sapi/phpdbg/phpdbg_parser.y +++ b/sapi/phpdbg/phpdbg_parser.y @@ -16,7 +16,6 @@ typedef void* yyscan_t; #include "phpdbg_cmd.h" #include "phpdbg_utils.h" -#include "phpdbg_cmd.h" #include "phpdbg_prompt.h" #include "phpdbg_parser.h" From d73b2f782e6e2487fde0d6d770454dc798dde335 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+ndossche@users.noreply.github.com> Date: Thu, 29 Jan 2026 18:26:50 +0100 Subject: [PATCH 3/4] Fix GH-21077: Accessing Dom\Node::baseURI can throw TypeError Prior to this patch there was a common read handler, and it relied on the dom class set in the intern document. However, Dom\Implementation allows creating DTDs unassociated with a document, so we can't rely on an intern document and the check fails. This causes the ZVAL_NULL() path to be taken. To solve this, just split the handler. Closes GH-21082. --- NEWS | 4 +++ ext/dom/dom_properties.h | 1 + ext/dom/node.c | 25 ++++++++++++----- ext/dom/php_dom.c | 2 +- ext/dom/tests/modern/common/gh21077.phpt | 28 +++++++++++++++++++ ...ent_implementation_createDocumentType.phpt | 8 +++--- ext/dom/tests/modern/xml/DTDNamedNodeMap.phpt | 2 +- 7 files changed, 57 insertions(+), 13 deletions(-) create mode 100644 ext/dom/tests/modern/common/gh21077.phpt diff --git a/NEWS b/NEWS index dbac366b38aae..cb2206ec1f5be 100644 --- a/NEWS +++ b/NEWS @@ -9,6 +9,10 @@ PHP NEWS . Fixed bug GH-21023 (CURLOPT_XFERINFOFUNCTION crash with a null callback). (David Carlier) +- DOM: + . Fixed bug GH-21077 (Accessing Dom\Node::baseURI can throw TypeError). + (ndossche) + - PDO_PGSQL: . Fixed bug GH-21055 (connection attribute status typo for GSS negotiation). (lsaos) diff --git a/ext/dom/dom_properties.h b/ext/dom/dom_properties.h index 338b4acc449f0..e8fd7535db8cd 100644 --- a/ext/dom/dom_properties.h +++ b/ext/dom/dom_properties.h @@ -134,6 +134,7 @@ zend_result dom_modern_node_prefix_read(dom_object *obj, zval *retval); zend_result dom_node_prefix_write(dom_object *obj, zval *newval); zend_result dom_node_local_name_read(dom_object *obj, zval *retval); zend_result dom_node_base_uri_read(dom_object *obj, zval *retval); +zend_result dom_modern_node_base_uri_read(dom_object *obj, zval *retval); zend_result dom_node_text_content_read(dom_object *obj, zval *retval); zend_result dom_node_text_content_write(dom_object *obj, zval *newval); diff --git a/ext/dom/node.c b/ext/dom/node.c index 0dd1b959752ef..b6a794edcdd88 100644 --- a/ext/dom/node.c +++ b/ext/dom/node.c @@ -659,14 +659,25 @@ zend_result dom_node_base_uri_read(dom_object *obj, zval *retval) ZVAL_STRING(retval, (const char *) baseuri); xmlFree(baseuri); } else { - if (php_dom_follow_spec_intern(obj)) { - if (nodep->doc->URL) { - ZVAL_STRING(retval, (const char *) nodep->doc->URL); - } else { - ZVAL_STRING(retval, "about:blank"); - } + ZVAL_NULL(retval); + } + + return SUCCESS; +} + +zend_result dom_modern_node_base_uri_read(dom_object *obj, zval *retval) +{ + DOM_PROP_NODE(xmlNodePtr, nodep, obj); + + xmlChar *baseuri = xmlNodeGetBase(nodep->doc, nodep); + if (baseuri) { + ZVAL_STRING(retval, (const char *) baseuri); + xmlFree(baseuri); + } else { + if (nodep->doc && nodep->doc->URL) { + ZVAL_STRING(retval, (const char *) nodep->doc->URL); } else { - ZVAL_NULL(retval); + ZVAL_STRING(retval, "about:blank"); } } diff --git a/ext/dom/php_dom.c b/ext/dom/php_dom.c index 22d52f123a13d..a4dbec0863161 100644 --- a/ext/dom/php_dom.c +++ b/ext/dom/php_dom.c @@ -892,7 +892,7 @@ PHP_MINIT_FUNCTION(dom) zend_hash_init(&dom_modern_node_prop_handlers, 0, NULL, NULL, true); DOM_REGISTER_PROP_HANDLER(&dom_modern_node_prop_handlers, "nodeType", dom_node_node_type_read, NULL); DOM_REGISTER_PROP_HANDLER(&dom_modern_node_prop_handlers, "nodeName", dom_node_node_name_read, NULL); - DOM_REGISTER_PROP_HANDLER(&dom_modern_node_prop_handlers, "baseURI", dom_node_base_uri_read, NULL); + DOM_REGISTER_PROP_HANDLER(&dom_modern_node_prop_handlers, "baseURI", dom_modern_node_base_uri_read, NULL); DOM_REGISTER_PROP_HANDLER(&dom_modern_node_prop_handlers, "isConnected", dom_node_is_connected_read, NULL); DOM_REGISTER_PROP_HANDLER(&dom_modern_node_prop_handlers, "ownerDocument", dom_node_owner_document_read, NULL); DOM_REGISTER_PROP_HANDLER(&dom_modern_node_prop_handlers, "parentNode", dom_node_parent_node_read, NULL); diff --git a/ext/dom/tests/modern/common/gh21077.phpt b/ext/dom/tests/modern/common/gh21077.phpt new file mode 100644 index 0000000000000..d9f9478925ee4 --- /dev/null +++ b/ext/dom/tests/modern/common/gh21077.phpt @@ -0,0 +1,28 @@ +--TEST-- +GH-21077 (Accessing Dom\Node::baseURI can throw TypeError) +--EXTENSIONS-- +dom +--CREDITS-- +mbeccati +--FILE-- +createDocumentType('html', 'publicId', 'systemId'); + +var_dump($node->baseURI); + +$dom = Dom\XMLDocument::createEmpty(); +$dom->append($node = $dom->importNode($node)); + +var_dump($dom->saveXML()); + +var_dump($node->baseURI); + +?> +--EXPECT-- +string(11) "about:blank" +string(84) " + +" +string(11) "about:blank" diff --git a/ext/dom/tests/modern/spec/Document_implementation_createDocumentType.phpt b/ext/dom/tests/modern/spec/Document_implementation_createDocumentType.phpt index bfb150b5cca89..74deed8bdc349 100644 --- a/ext/dom/tests/modern/spec/Document_implementation_createDocumentType.phpt +++ b/ext/dom/tests/modern/spec/Document_implementation_createDocumentType.phpt @@ -43,7 +43,7 @@ object(Dom\DocumentType)#3 (19) { ["nodeName"]=> string(5) "qname" ["baseURI"]=> - NULL + string(11) "about:blank" ["isConnected"]=> bool(false) ["parentNode"]=> @@ -86,7 +86,7 @@ object(Dom\DocumentType)#2 (19) { ["nodeName"]=> string(5) "qname" ["baseURI"]=> - NULL + string(11) "about:blank" ["isConnected"]=> bool(false) ["parentNode"]=> @@ -129,7 +129,7 @@ object(Dom\DocumentType)#1 (19) { ["nodeName"]=> string(5) "qname" ["baseURI"]=> - NULL + string(11) "about:blank" ["isConnected"]=> bool(false) ["parentNode"]=> @@ -172,7 +172,7 @@ object(Dom\DocumentType)#4 (19) { ["nodeName"]=> string(5) "qname" ["baseURI"]=> - NULL + string(11) "about:blank" ["isConnected"]=> bool(false) ["parentNode"]=> diff --git a/ext/dom/tests/modern/xml/DTDNamedNodeMap.phpt b/ext/dom/tests/modern/xml/DTDNamedNodeMap.phpt index fb0853939f88e..f9bb1f7a996e6 100644 --- a/ext/dom/tests/modern/xml/DTDNamedNodeMap.phpt +++ b/ext/dom/tests/modern/xml/DTDNamedNodeMap.phpt @@ -148,7 +148,7 @@ object(Dom\Notation)#4 (13) { ["nodeName"]=> string(3) "GIF" ["baseURI"]=> - NULL + string(11) "about:blank" ["isConnected"]=> bool(false) ["parentNode"]=> From d1c1a9fa82bdfbdb4a0a2e0f72b428552167ebe8 Mon Sep 17 00:00:00 2001 From: Arshid Date: Fri, 30 Jan 2026 23:28:25 +0530 Subject: [PATCH 4/4] [skip ci] Remove unused arg from zend_throw_incdec_ref_error() (GH-21081) --- Zend/zend_execute.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index e95931276ef51..42f8d46d5a3d3 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -2185,8 +2185,7 @@ static zend_property_info *zend_get_prop_not_accepting_double(zend_reference *re return NULL; } -static ZEND_COLD zend_long zend_throw_incdec_ref_error( - zend_reference *ref, zend_property_info *error_prop OPLINE_DC) +static ZEND_COLD zend_long zend_throw_incdec_ref_error(zend_property_info *error_prop OPLINE_DC) { zend_string *type_str = zend_type_to_string(error_prop->type); if (ZEND_IS_INCREMENT(opline->opcode)) { @@ -2247,7 +2246,7 @@ static void zend_incdec_typed_ref(zend_reference *ref, zval *copy OPLINE_DC EXEC if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_DOUBLE) && Z_TYPE_P(copy) == IS_LONG) { zend_property_info *error_prop = zend_get_prop_not_accepting_double(ref); if (UNEXPECTED(error_prop)) { - zend_long val = zend_throw_incdec_ref_error(ref, error_prop OPLINE_CC); + zend_long val = zend_throw_incdec_ref_error(error_prop OPLINE_CC); ZVAL_LONG(var_ptr, val); } } else if (UNEXPECTED(!zend_verify_ref_assignable_zval(ref, var_ptr, EX_USES_STRICT_TYPES()))) {