Skip to content

Commit 61b7370

Browse files
committed
Merge branch 'PHP-8.3'
* PHP-8.3: Fix GH-12929: SimpleXMLElement with stream_wrapper_register can segfault Fix getting the address of an uninitialized property of a SimpleXMLElement resulting in a crash Fix GH-12962: Double free of init_file in phpdbg_prompt.c
2 parents d8268f1 + f75931a commit 61b7370

File tree

6 files changed

+71
-7
lines changed

6 files changed

+71
-7
lines changed

ext/simplexml/simplexml.c

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -415,8 +415,6 @@ static zval *sxe_prop_dim_write(zend_object *object, zval *member, zval *value,
415415

416416
GET_NODE(sxe, node);
417417

418-
php_libxml_invalidate_node_list_cache_from_doc(node->doc);
419-
420418
if (sxe->iter.type == SXE_ITER_ATTRLIST) {
421419
attribs = 1;
422420
elements = 0;
@@ -477,6 +475,8 @@ static zval *sxe_prop_dim_write(zend_object *object, zval *member, zval *value,
477475
}
478476

479477
if (node) {
478+
php_libxml_invalidate_node_list_cache_from_doc(node->doc);
479+
480480
if (attribs) {
481481
if (Z_TYPE_P(member) == IS_LONG) {
482482
while (attr && nodendx <= Z_LVAL_P(member)) {
@@ -619,6 +619,9 @@ static zval *sxe_property_get_adr(zend_object *object, zend_string *zname, int f
619619

620620
sxe = php_sxe_fetch_object(object);
621621
GET_NODE(sxe, node);
622+
if (UNEXPECTED(!node)) {
623+
return &EG(error_zval);
624+
}
622625
name = ZSTR_VAL(zname);
623626
node = sxe_get_element_by_name(sxe, node, name, &type);
624627
if (node) {
@@ -788,8 +791,6 @@ static void sxe_prop_dim_delete(zend_object *object, zval *member, bool elements
788791

789792
GET_NODE(sxe, node);
790793

791-
php_libxml_invalidate_node_list_cache_from_doc(node->doc);
792-
793794
if (Z_TYPE_P(member) == IS_LONG) {
794795
if (sxe->iter.type != SXE_ITER_ATTRLIST) {
795796
attribs = 0;
@@ -813,6 +814,8 @@ static void sxe_prop_dim_delete(zend_object *object, zval *member, bool elements
813814
}
814815

815816
if (node) {
817+
php_libxml_invalidate_node_list_cache_from_doc(node->doc);
818+
816819
if (attribs) {
817820
if (Z_TYPE_P(member) == IS_LONG) {
818821
int nodendx = 0;
@@ -1639,8 +1642,6 @@ PHP_METHOD(SimpleXMLElement, addChild)
16391642
sxe = Z_SXEOBJ_P(ZEND_THIS);
16401643
GET_NODE(sxe, node);
16411644

1642-
php_libxml_invalidate_node_list_cache_from_doc(node->doc);
1643-
16441645
if (sxe->iter.type == SXE_ITER_ATTRLIST) {
16451646
php_error_docref(NULL, E_WARNING, "Cannot add element to attributes");
16461647
return;
@@ -1653,6 +1654,8 @@ PHP_METHOD(SimpleXMLElement, addChild)
16531654
return;
16541655
}
16551656

1657+
php_libxml_invalidate_node_list_cache_from_doc(node->doc);
1658+
16561659
localname = xmlSplitQName2((xmlChar *)qname, &prefix);
16571660
if (localname == NULL) {
16581661
localname = xmlStrdup((xmlChar *)qname);
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
--TEST--
2+
Getting the address of an uninitialized property of a SimpleXMLElement
3+
--EXTENSIONS--
4+
simplexml
5+
--FILE--
6+
<?php
7+
8+
$rc = new ReflectionClass('SimpleXMLElement');
9+
$sxe = $rc->newInstanceWithoutConstructor();
10+
$sxe->a['b'] = 'b';
11+
12+
?>
13+
--EXPECTF--
14+
Fatal error: Uncaught Error: SimpleXMLElement is not properly initialized in %s:%d
15+
Stack trace:
16+
#0 {main}
17+
thrown in %s on line %d

ext/simplexml/tests/gh12929.phpt

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
--TEST--
2+
GH-12929 (SimpleXMLElement with stream_wrapper_register can segfault)
3+
--EXTENSIONS--
4+
simplexml
5+
--FILE--
6+
<?php
7+
$scheme = "foo1";
8+
stream_wrapper_register($scheme, "SimpleXMLIterator");
9+
try {
10+
file_get_contents($scheme . "://x");
11+
} catch (Error $e) {
12+
echo $e->getMessage(), "\n";
13+
echo $e->getPrevious()->getMessage(), "\n";
14+
}
15+
16+
$scheme = "foo2";
17+
stream_wrapper_register($scheme, "SimpleXMLElement");
18+
try {
19+
file_get_contents($scheme . "://x");
20+
} catch (Error $e) {
21+
echo $e->getMessage(), "\n";
22+
echo $e->getPrevious()->getMessage(), "\n";
23+
}
24+
?>
25+
--EXPECT--
26+
It's not possible to assign a complex type to properties, resource given
27+
SimpleXMLElement is not properly initialized
28+
It's not possible to assign a complex type to properties, resource given
29+
SimpleXMLElement is not properly initialized

sapi/phpdbg/phpdbg_prompt.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,7 @@ void phpdbg_init(char *init_file, size_t init_file_len, bool use_default) /* {{{
363363
}
364364

365365
ZEND_IGNORE_VALUE(asprintf(&init_file, "%s/%s", scan_dir, PHPDBG_INIT_FILENAME));
366-
phpdbg_try_file_init(init_file, strlen(init_file), 1);
366+
phpdbg_try_file_init(init_file, strlen(init_file), 0);
367367
free(init_file);
368368
if (i == -1) {
369369
break;

sapi/phpdbg/tests/gh12962.phpt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
--TEST--
2+
GH-12962 (Double free of init_file in phpdbg_prompt.c)
3+
--SKIPIF--
4+
<?php
5+
if (!getenv('TEST_PHPDBG_EXECUTABLE')) die("SKIP: No TEST_PHPDBG_EXECUTABLE specified");
6+
?>
7+
--FILE--
8+
<?php
9+
putenv('PHP_INI_SCAN_DIR='.__DIR__."/gh12962");
10+
passthru($_ENV['TEST_PHPDBG_EXECUTABLE'] . " -q");
11+
?>
12+
--EXPECT--
13+
Executed .phpdbginit

sapi/phpdbg/tests/gh12962/.phpdbginit

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
ev "Executed .phpdbginit"
2+
q

0 commit comments

Comments
 (0)