From 08ba240c81811dda0dc672c9d6cacb3bb10c5741 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+ndossche@users.noreply.github.com> Date: Tue, 11 Nov 2025 11:19:29 +0100 Subject: [PATCH 1/5] simplexml: Avoid double lookups and unnecessary allocations in getNamespaces() (#20447) --- ext/simplexml/simplexml.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/ext/simplexml/simplexml.c b/ext/simplexml/simplexml.c index d3248bb81208..16a8aaa22fc3 100644 --- a/ext/simplexml/simplexml.c +++ b/ext/simplexml/simplexml.c @@ -1413,14 +1413,10 @@ PHP_METHOD(SimpleXMLElement, asXML) static inline void sxe_add_namespace_name_raw(zval *return_value, const char *prefix, const char *href) { - zend_string *key = zend_string_init(prefix, strlen(prefix), 0); - zval zv; - - if (!zend_hash_exists(Z_ARRVAL_P(return_value), key)) { - ZVAL_STRING(&zv, href); - zend_hash_add_new(Z_ARRVAL_P(return_value), key, &zv); + zval *zv = zend_hash_str_lookup(Z_ARRVAL_P(return_value), prefix, strlen(prefix)); + if (Z_ISNULL_P(zv)) { + ZVAL_STRING(zv, href); } - zend_string_release_ex(key, 0); } static inline void sxe_add_namespace_name(zval *return_value, xmlNsPtr ns) /* {{{ */ From ee9773bdc6484496d1f5cf258b0bf48c4ba1c93f Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+ndossche@users.noreply.github.com> Date: Tue, 11 Nov 2025 13:40:04 +0100 Subject: [PATCH 2/5] Fix nightly failure due to OnChangeMemoryLimit changes (#20450) --- main/main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/main/main.c b/main/main.c index cfa84ba0959b..25cfc4de1e7d 100644 --- a/main/main.c +++ b/main/main.c @@ -347,6 +347,7 @@ static PHP_INI_MH(OnChangeMemoryLimit) zend_ini_entry *max_mem_limit_ini = zend_hash_str_find_ptr(EG(ini_directives), ZEND_STRL("max_memory_limit")); entry->value = zend_string_init(ZSTR_VAL(max_mem_limit_ini->value), ZSTR_LEN(max_mem_limit_ini->value), true); + GC_MAKE_PERSISTENT_LOCAL(entry->value); PG(memory_limit) = PG(max_memory_limit); return SUCCESS; From 618e576614004c8853a3660435f8552b0cfbe77b Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+ndossche@users.noreply.github.com> Date: Tue, 11 Nov 2025 13:41:18 +0100 Subject: [PATCH 3/5] Minor DOM cleanups --- ext/dom/element.c | 9 +-------- ext/dom/node.c | 17 ++++------------- 2 files changed, 5 insertions(+), 21 deletions(-) diff --git a/ext/dom/element.c b/ext/dom/element.c index cf1a762768a8..797f215e173d 100644 --- a/ext/dom/element.c +++ b/ext/dom/element.c @@ -1210,19 +1210,17 @@ Since: DOM Level 2 */ PHP_METHOD(DOMElement, getAttributeNodeNS) { - zval *id; xmlNodePtr elemp; xmlAttrPtr attrp; dom_object *intern; size_t uri_len, name_len; char *uri, *name; - id = ZEND_THIS; if (zend_parse_parameters(ZEND_NUM_ARGS(), "s!s", &uri, &uri_len, &name, &name_len) == FAILURE) { RETURN_THROWS(); } - DOM_GET_OBJ(elemp, id, xmlNodePtr, intern); + DOM_GET_OBJ(elemp, ZEND_THIS, xmlNodePtr, intern); bool follow_spec = php_dom_follow_spec_intern(intern); if (follow_spec && uri_len == 0) { @@ -1239,16 +1237,11 @@ PHP_METHOD(DOMElement, getAttributeNodeNS) /* Keep parent alive, because we're a fake child. */ GC_ADDREF(&intern->std); (void) php_dom_create_fake_namespace_decl(elemp, nsptr, return_value, intern); - } else { - RETURN_NULL(); } - } else { - RETURN_NULL(); } } else { DOM_RET_OBJ((xmlNodePtr) attrp, intern); } - } /* }}} end dom_element_get_attribute_node_ns */ diff --git a/ext/dom/node.c b/ext/dom/node.c index 40aaf2766926..debc08c4958c 100644 --- a/ext/dom/node.c +++ b/ext/dom/node.c @@ -1878,8 +1878,7 @@ static void dom_node_lookup_prefix(INTERNAL_FUNCTION_PARAMETERS, bool modern) case XML_DOCUMENT_FRAG_NODE: case XML_DOCUMENT_TYPE_NODE: case XML_DTD_NODE: - RETURN_NULL(); - break; + return; default: lookupp = nodep->parent; } @@ -1898,8 +1897,6 @@ static void dom_node_lookup_prefix(INTERNAL_FUNCTION_PARAMETERS, bool modern) } } } - - RETURN_NULL(); } PHP_METHOD(DOMNode, lookupPrefix) @@ -2065,16 +2062,14 @@ PHP_METHOD(DOMNode, lookupNamespaceURI) prefix = NULL; } const char *ns_uri = dom_locate_a_namespace(nodep, prefix); - if (ns_uri == NULL) { - RETURN_NULL(); - } else { + if (ns_uri != NULL) { RETURN_STRING(ns_uri); } } else { if (nodep->type == XML_DOCUMENT_NODE || nodep->type == XML_HTML_DOCUMENT_NODE) { nodep = xmlDocGetRootElement((xmlDocPtr) nodep); if (nodep == NULL) { - RETURN_NULL(); + return; } } @@ -2083,8 +2078,6 @@ PHP_METHOD(DOMNode, lookupNamespaceURI) RETURN_STRING((char *) nsptr->href); } } - - RETURN_NULL(); } /* }}} end dom_node_lookup_namespace_uri */ @@ -2294,13 +2287,12 @@ static void dom_node_get_node_path(INTERNAL_FUNCTION_PARAMETERS, bool throw) zval *id; xmlNode *nodep; dom_object *intern; - char *value; ZEND_PARSE_PARAMETERS_NONE(); DOM_GET_THIS_OBJ(nodep, id, xmlNodePtr, intern); - value = (char *) xmlGetNodePath(nodep); + char *value = (char *) xmlGetNodePath(nodep); if (value == NULL) { /* This is only possible when an invalid argument is passed (e.g. namespace declaration, but that's not the case for this call site), * or on allocation failure. So in other words, this only happens on allocation failure. */ @@ -2308,7 +2300,6 @@ static void dom_node_get_node_path(INTERNAL_FUNCTION_PARAMETERS, bool throw) php_dom_throw_error(INVALID_STATE_ERR, /* strict */ true); RETURN_THROWS(); } - RETURN_NULL(); } else { RETVAL_STRING(value); xmlFree(value); From a596e05cf3563f5f43bf02d39f5c74ab47344273 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+ndossche@users.noreply.github.com> Date: Tue, 11 Nov 2025 13:44:13 +0100 Subject: [PATCH 4/5] phar: Make phar_is_tar() and referenced functions const correct (#20451) --- ext/phar/phar.c | 2 +- ext/phar/phar_internal.h | 2 +- ext/phar/tar.c | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/ext/phar/phar.c b/ext/phar/phar.c index b7becf27e32d..51b28ec2b749 100644 --- a/ext/phar/phar.c +++ b/ext/phar/phar.c @@ -1719,7 +1719,7 @@ static zend_result phar_open_from_fp(php_stream* fp, char *fname, size_t fname_l } if (got >= 512) { - if (phar_is_tar((char *) pos, fname)) { /* TODO: fix const correctness */ + if (phar_is_tar(pos, fname)) { php_stream_rewind(fp); return phar_parse_tarfile(fp, fname, fname_len, alias, alias_len, pphar, compression, error); } diff --git a/ext/phar/phar_internal.h b/ext/phar/phar_internal.h index bd3d7158c8e8..5acb0873ebdb 100644 --- a/ext/phar/phar_internal.h +++ b/ext/phar/phar_internal.h @@ -443,7 +443,7 @@ zend_result phar_open_archive_fp(phar_archive_data *phar); zend_result phar_copy_on_write(phar_archive_data **pphar); /* tar functions in tar.c */ -bool phar_is_tar(char *buf, char *fname); +bool phar_is_tar(const char *buf, const char *fname); zend_result phar_parse_tarfile(php_stream* fp, char *fname, size_t fname_len, char *alias, size_t alias_len, phar_archive_data** pphar, uint32_t compression, char **error); ZEND_ATTRIBUTE_NONNULL_ARGS(1, 7, 8) zend_result phar_open_or_create_tar(char *fname, size_t fname_len, char *alias, size_t alias_len, bool is_data, uint32_t options, phar_archive_data** pphar, char **error); ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) void phar_tar_flush(phar_archive_data *phar, zend_string *user_stub, bool is_default_stub, char **error); diff --git a/ext/phar/tar.c b/ext/phar/tar.c index 4847597cce2e..67994289d0a9 100644 --- a/ext/phar/tar.c +++ b/ext/phar/tar.c @@ -87,10 +87,10 @@ static zend_result phar_tar_octal(char *buf, uint32_t val, size_t len) /* {{{ */ } /* }}} */ -static uint32_t phar_tar_checksum(char *buf, size_t len) /* {{{ */ +static uint32_t phar_tar_checksum(const char *buf, size_t len) /* {{{ */ { uint32_t sum = 0; - char *end = buf + len; + const char *end = buf + len; while (buf != end) { sum += (unsigned char)*buf; @@ -100,7 +100,7 @@ static uint32_t phar_tar_checksum(char *buf, size_t len) /* {{{ */ } /* }}} */ -bool phar_is_tar(char *buf, char *fname) /* {{{ */ +bool phar_is_tar(const char *buf, const char *fname) /* {{{ */ { tar_header *header = (tar_header *) buf; uint32_t checksum = phar_tar_number(header->checksum, sizeof(header->checksum)); From ddf584c71ac258a83e77a7cb0bc63747880d4361 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+ndossche@users.noreply.github.com> Date: Tue, 11 Nov 2025 13:46:29 +0100 Subject: [PATCH 5/5] [ci skip] Fix NEWS ordering --- NEWS | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index 4ff3472d926b..3f519e5eec40 100644 --- a/NEWS +++ b/NEWS @@ -9,9 +9,6 @@ PHP NEWS . Fixed bug GH-17951 (memory_limit is not always limited by max_memory_limit). (manuelm) -- Standard: - . Fix memory leak in array_diff() with custom type checks. (ndossche) - - Opcache: . Fixed bug GH-20329 (opcache.file_cache broken with full interned string buffer). (Arnaud) @@ -20,6 +17,9 @@ PHP NEWS . Fixed bug GH-20442 (Phar does not respect case-insensitiveness of __halt_compiler() when reading stub). (ndossche, TimWolla) +- Standard: + . Fix memory leak in array_diff() with custom type checks. (ndossche) + 06 Nov 2025, PHP 8.5.0RC4 - Core: