Skip to content

Commit dba5fef

Browse files
committed
Merge remote-tracking branch 'origin/PHP-8.4' into heap_validation
2 parents 2e34a3e + c772963 commit dba5fef

File tree

17 files changed

+307
-17
lines changed

17 files changed

+307
-17
lines changed

NEWS

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,18 @@ PHP NEWS
1212
released on bailout). (DanielEScherzer and ilutov)
1313
. Fixed GH-18695 (zend_ast_export() - float number is not preserved).
1414
(Oleg Efimov)
15+
. Fix handling of references in zval_try_get_long(). (nielsdos)
1516

1617
- Curl:
1718
. Fix memory leak when setting a list via curl_setopt fails. (nielsdos)
1819

1920
- Date:
2021
. Fix leaks with multiple calls to DatePeriod iterator current(). (nielsdos)
2122

23+
- DOM:
24+
. Fixed bug GH-18744 (classList works not correctly if copy HTMLElement by
25+
clone keyword). (nielsdos)
26+
2227
- FPM:
2328
. Fixed GH-18662 (fpm_get_status segfault). (txuna)
2429

@@ -29,6 +34,8 @@ PHP NEWS
2934
- OpenSSL:
3035
. Fix memory leak of X509_STORE in php_openssl_setup_verify() on failure.
3136
(nielsdos)
37+
. Fixed bug #74796 (Requests through http proxy set peer name).
38+
(Jakub Zelenka)
3239

3340
- Phar:
3441
. Add missing filter cleanups on phar failure. (nielsdos)
@@ -55,6 +62,7 @@ PHP NEWS
5562

5663
- Tidy:
5764
. Fix memory leak in tidy output handler on error. (nielsdos)
65+
. Fix tidyOptIsReadonly deprecation, using tidyOptGetCategory. (David Carlier)
5866

5967
06 Jun 2025, PHP 8.4.8
6068

Zend/zend_alloc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3449,7 +3449,7 @@ ZEND_API zend_mm_storage *zend_mm_get_storage(zend_mm_heap *heap)
34493449
ZEND_ASAN_POISON_MEMORY_REGION(heap, sizeof(zend_mm_heap));
34503450
return ret;
34513451
#else
3452-
return NULL
3452+
return NULL;
34533453
#endif
34543454
}
34553455

Zend/zend_operators.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,7 @@ static zend_always_inline zend_result zendi_try_convert_scalar_to_number(zval *o
378378
static zend_never_inline zend_long ZEND_FASTCALL zendi_try_get_long(const zval *op, bool *failed) /* {{{ */
379379
{
380380
*failed = 0;
381+
try_again:
381382
switch (Z_TYPE_P(op)) {
382383
case IS_NULL:
383384
case IS_FALSE:
@@ -448,6 +449,14 @@ static zend_never_inline zend_long ZEND_FASTCALL zendi_try_get_long(const zval *
448449
case IS_ARRAY:
449450
*failed = 1;
450451
return 0;
452+
case IS_REFERENCE:
453+
op = Z_REFVAL_P(op);
454+
if (Z_TYPE_P(op) == IS_LONG) {
455+
return Z_LVAL_P(op);
456+
} else {
457+
goto try_again;
458+
}
459+
break;
451460
EMPTY_SWITCH_DEFAULT_CASE()
452461
}
453462
}

ext/dom/element.c

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -177,10 +177,7 @@ zend_result dom_element_class_name_write(dom_object *obj, zval *newval)
177177
}
178178
/* }}} */
179179

180-
/* {{{ classList TokenList
181-
URL: https://dom.spec.whatwg.org/#dom-element-classlist
182-
*/
183-
zend_result dom_element_class_list_read(dom_object *obj, zval *retval)
180+
zval *dom_element_class_list_zval(dom_object *obj)
184181
{
185182
const uint32_t PROP_INDEX = 0;
186183

@@ -191,7 +188,15 @@ zend_result dom_element_class_list_read(dom_object *obj, zval *retval)
191188
ZEND_ASSERT(OBJ_PROP_TO_NUM(prop_info->offset) == PROP_INDEX);
192189
#endif
193190

194-
zval *cached_token_list = OBJ_PROP_NUM(&obj->std, PROP_INDEX);
191+
return OBJ_PROP_NUM(&obj->std, PROP_INDEX);
192+
}
193+
194+
/* {{{ classList TokenList
195+
URL: https://dom.spec.whatwg.org/#dom-element-classlist
196+
*/
197+
zend_result dom_element_class_list_read(dom_object *obj, zval *retval)
198+
{
199+
zval *cached_token_list = dom_element_class_list_zval(obj);
195200
if (Z_ISUNDEF_P(cached_token_list)) {
196201
object_init_ex(cached_token_list, dom_token_list_class_entry);
197202
dom_token_list_object *intern = php_dom_token_list_from_obj(Z_OBJ_P(cached_token_list));

ext/dom/php_dom.c

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ static zend_object_handlers dom_modern_nodelist_object_handlers;
101101
static zend_object_handlers dom_html_collection_object_handlers;
102102
static zend_object_handlers dom_object_namespace_node_handlers;
103103
static zend_object_handlers dom_modern_domimplementation_object_handlers;
104+
static zend_object_handlers dom_modern_element_object_handlers;
104105
static zend_object_handlers dom_token_list_object_handlers;
105106
#ifdef LIBXML_XPATH_ENABLED
106107
zend_object_handlers dom_xpath_object_handlers;
@@ -669,6 +670,21 @@ static zend_object *dom_objects_store_clone_obj(zend_object *zobject) /* {{{ */
669670
}
670671
/* }}} */
671672

673+
static zend_object *dom_modern_element_clone_obj(zend_object *zobject)
674+
{
675+
zend_object *clone = dom_objects_store_clone_obj(zobject);
676+
677+
/* The $classList property is unique per element, and cached due to its [[SameObject]] requirement.
678+
* Remove it from the clone so the clone will get a fresh instance upon demand. */
679+
zval *class_list = dom_element_class_list_zval(php_dom_obj_from_obj(clone));
680+
if (!Z_ISUNDEF_P(class_list)) {
681+
zval_ptr_dtor(class_list);
682+
ZVAL_UNDEF(class_list);
683+
}
684+
685+
return clone;
686+
}
687+
672688
static zend_object *dom_object_namespace_node_clone_obj(zend_object *zobject)
673689
{
674690
dom_object_namespace_node *intern = php_dom_namespace_node_obj_from_obj(zobject);
@@ -778,6 +794,9 @@ PHP_MINIT_FUNCTION(dom)
778794
* one instance per parent object. */
779795
dom_modern_domimplementation_object_handlers.clone_obj = NULL;
780796

797+
memcpy(&dom_modern_element_object_handlers, &dom_object_handlers, sizeof(zend_object_handlers));
798+
dom_modern_element_object_handlers.clone_obj = dom_modern_element_clone_obj;
799+
781800
memcpy(&dom_nnodemap_object_handlers, &dom_object_handlers, sizeof(zend_object_handlers));
782801
dom_nnodemap_object_handlers.free_obj = dom_nnodemap_objects_free_storage;
783802
dom_nnodemap_object_handlers.read_dimension = dom_nodemap_read_dimension;
@@ -1108,7 +1127,7 @@ PHP_MINIT_FUNCTION(dom)
11081127

11091128
dom_modern_element_class_entry = register_class_Dom_Element(dom_modern_node_class_entry, dom_modern_parentnode_class_entry, dom_modern_childnode_class_entry);
11101129
dom_modern_element_class_entry->create_object = dom_objects_new;
1111-
dom_modern_element_class_entry->default_object_handlers = &dom_object_handlers;
1130+
dom_modern_element_class_entry->default_object_handlers = &dom_modern_element_object_handlers;
11121131

11131132
zend_hash_init(&dom_modern_element_prop_handlers, 0, NULL, NULL, true);
11141133
DOM_REGISTER_PROP_HANDLER(&dom_modern_element_prop_handlers, "namespaceURI", dom_node_namespace_uri_read, NULL);
@@ -1132,7 +1151,7 @@ PHP_MINIT_FUNCTION(dom)
11321151

11331152
dom_html_element_class_entry = register_class_Dom_HTMLElement(dom_modern_element_class_entry);
11341153
dom_html_element_class_entry->create_object = dom_objects_new;
1135-
dom_html_element_class_entry->default_object_handlers = &dom_object_handlers;
1154+
dom_html_element_class_entry->default_object_handlers = &dom_modern_element_object_handlers;
11361155
zend_hash_add_new_ptr(&classes, dom_html_element_class_entry->name, &dom_modern_element_prop_handlers);
11371156

11381157
dom_text_class_entry = register_class_DOMText(dom_characterdata_class_entry);

ext/dom/php_dom.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,7 @@ bool php_dom_create_nullable_object(xmlNodePtr obj, zval *return_value, dom_obje
187187
xmlNodePtr dom_clone_node(php_dom_libxml_ns_mapper *ns_mapper, xmlNodePtr node, xmlDocPtr doc, bool recursive);
188188
void dom_set_document_ref_pointers(xmlNodePtr node, php_libxml_ref_obj *document);
189189
void dom_set_document_ref_pointers_attr(xmlAttrPtr attr, php_libxml_ref_obj *document);
190+
zval *dom_element_class_list_zval(dom_object *obj);
190191

191192
typedef enum {
192193
DOM_LOAD_STRING = 0,
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
--TEST--
2+
GH-18744 (classList works not correctly if copy HTMLElement by clone keyword.)
3+
--EXTENSIONS--
4+
dom
5+
--FILE--
6+
<?php
7+
8+
$doc = \Dom\HTMLDocument::createEmpty();
9+
$ele1 = $doc->createElement('div');
10+
$ele1->classList->add('foo');
11+
$ele2 = clone $ele1;
12+
$ele2->classList->add('bar');
13+
14+
echo "Element1 class: " . $ele1->getAttribute('class');
15+
echo "\n";
16+
echo "Element2 class: " . $ele2->getAttribute('class');
17+
echo "\n";
18+
19+
var_dump($ele1->classList !== $ele2->classList);
20+
// These comparisons are not pointless: they're getters and should not create new objects
21+
var_dump($ele1->classList === $ele1->classList);
22+
var_dump($ele2->classList === $ele2->classList);
23+
24+
?>
25+
--EXPECT--
26+
Element1 class: foo
27+
Element2 class: foo bar
28+
bool(true)
29+
bool(true)
30+
bool(true)

ext/intl/dateformat/dateformat_parse.c

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -185,12 +185,10 @@ PHP_METHOD(IntlDateFormatter, parseToCalendar)
185185
DATE_FORMAT_METHOD_FETCH_OBJECT;
186186

187187
if (z_parse_pos) {
188-
zval *z_parse_pos_tmp = z_parse_pos;
189-
ZVAL_DEREF(z_parse_pos_tmp);
190-
bool failed = false;
191-
zend_long long_parse_pos = zval_try_get_long(z_parse_pos_tmp, &failed);
188+
bool failed;
189+
zend_long long_parse_pos = zval_try_get_long(z_parse_pos, &failed);
192190
if (failed) {
193-
zend_argument_type_error(2, "must be of type int, %s given", zend_zval_value_name(z_parse_pos_tmp));
191+
zend_argument_type_error(2, "must be of type int, %s given", zend_zval_value_name(z_parse_pos));
194192
RETURN_THROWS();
195193
}
196194
if (ZEND_LONG_INT_OVFL(long_parse_pos)) {

ext/mbstring/mbstring.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3930,7 +3930,7 @@ static uint32_t *make_conversion_map(HashTable *target_hash, size_t *conversion_
39303930
uint32_t *mapelm = convmap;
39313931

39323932
ZEND_HASH_FOREACH_VAL(target_hash, hash_entry) {
3933-
bool failed = true;
3933+
bool failed;
39343934
zend_long tmp = zval_try_get_long(hash_entry, &failed);
39353935
if (failed) {
39363936
efree(convmap);
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
--TEST--
2+
mb_encode_numericentity() reference handling
3+
--EXTENSIONS--
4+
mbstring
5+
--FILE--
6+
<?php
7+
$n = 0;
8+
$convmap = [&$n, 0x1FFFFF, 0, 0x10FFFF];
9+
var_dump(mb_encode_numericentity("", $convmap, "utf8"));
10+
?>
11+
--EXPECT--
12+
string(0) ""

0 commit comments

Comments
 (0)