Skip to content

Commit fc7bab3

Browse files
committed
Throw on uninitialized SimpleXMLElement
Elevate this warning into an Error, as usual. Add a few checks in places that were missing them.
1 parent f5e6f9b commit fc7bab3

File tree

4 files changed

+78
-25
lines changed

4 files changed

+78
-25
lines changed

ext/simplexml/php_simplexml_exports.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
__n = (__s)->node->node; \
3232
} else { \
3333
__n = NULL; \
34-
php_error_docref(NULL, E_WARNING, "Node no longer exists"); \
34+
zend_throw_error(NULL, "SimpleXMLElement is not properly initialized"); \
3535
} \
3636
}
3737

ext/simplexml/simplexml.c

+20-22
Original file line numberDiff line numberDiff line change
@@ -82,15 +82,6 @@ static void _node_as_zval(php_sxe_object *sxe, xmlNodePtr node, zval *value, SXE
8282
}
8383
/* }}} */
8484

85-
#define GET_NODE(__s, __n) { \
86-
if ((__s)->node && (__s)->node->node) { \
87-
__n = (__s)->node->node; \
88-
} else { \
89-
__n = NULL; \
90-
php_error_docref(NULL, E_WARNING, "Node no longer exists"); \
91-
} \
92-
}
93-
9485
static xmlNodePtr php_sxe_get_first_node(php_sxe_object *sxe, xmlNodePtr node) /* {{{ */
9586
{
9687
php_sxe_object *intern;
@@ -1323,18 +1314,15 @@ SXE_METHOD(xpath)
13231314
return; /* attributes don't have attributes */
13241315
}
13251316

1317+
GET_NODE(sxe, nodeptr);
1318+
nodeptr = php_sxe_get_first_node(sxe, nodeptr);
1319+
if (!nodeptr) {
1320+
return;
1321+
}
1322+
13261323
if (!sxe->xpath) {
13271324
sxe->xpath = xmlXPathNewContext((xmlDocPtr) sxe->document->ptr);
13281325
}
1329-
if (!sxe->node) {
1330-
php_libxml_increment_node_ptr((php_libxml_node_object *)sxe, xmlDocGetRootElement((xmlDocPtr) sxe->document->ptr), NULL);
1331-
if (!sxe->node) {
1332-
RETURN_FALSE;
1333-
}
1334-
}
1335-
1336-
nodeptr = php_sxe_get_first_node(sxe, sxe->node->node);
1337-
13381326
sxe->xpath->node = nodeptr;
13391327

13401328
ns = xmlGetNsList((xmlDocPtr) sxe->document->ptr, nodeptr);
@@ -1599,9 +1587,14 @@ SXE_METHOD(getDocNamespaces)
15991587
}
16001588

16011589
sxe = Z_SXEOBJ_P(ZEND_THIS);
1602-
if(from_root){
1590+
if (from_root) {
1591+
if (!sxe->document) {
1592+
zend_throw_error(NULL, "SimpleXMLElement is not properly initialized");
1593+
RETURN_THROWS();
1594+
}
1595+
16031596
node = xmlDocGetRootElement((xmlDocPtr)sxe->document->ptr);
1604-
}else{
1597+
} else {
16051598
GET_NODE(sxe, node);
16061599
}
16071600

@@ -1635,6 +1628,9 @@ SXE_METHOD(children)
16351628

16361629
GET_NODE(sxe, node);
16371630
node = php_sxe_get_first_node(sxe, node);
1631+
if (!node) {
1632+
return;
1633+
}
16381634

16391635
_node_as_zval(sxe, node, return_value, SXE_ITER_CHILD, NULL, (xmlChar *)nsprefix, isprefix);
16401636

@@ -1680,13 +1676,15 @@ SXE_METHOD(attributes)
16801676

16811677
sxe = Z_SXEOBJ_P(ZEND_THIS);
16821678
GET_NODE(sxe, node);
1679+
node = php_sxe_get_first_node(sxe, node);
1680+
if (!node) {
1681+
return;
1682+
}
16831683

16841684
if (sxe->iter.type == SXE_ITER_ATTRLIST) {
16851685
return; /* attributes don't have attributes */
16861686
}
16871687

1688-
node = php_sxe_get_first_node(sxe, node);
1689-
16901688
_node_as_zval(sxe, node, return_value, SXE_ITER_ATTRLIST, NULL, (xmlChar *)nsprefix, isprefix);
16911689
}
16921690
/* }}} */

ext/simplexml/tests/SimpleXMLElement_xpath.phpt

+6-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,11 @@ const XML_PARSE_RECOVER = 1;
1111
$xml = @simplexml_load_string("XXXXXXX^", 'SimpleXMLElement', XML_PARSE_RECOVER);
1212

1313
// $xml is supposed to hold a SimpleXMLElement, but not FALSE/NULL
14-
var_dump($xml->xpath("BBBB"));
14+
try {
15+
var_dump($xml->xpath("BBBB"));
16+
} catch (Error $e) {
17+
echo $e->getMessage(), "\n";
18+
}
1519
?>
1620
--EXPECT--
17-
bool(false)
21+
SimpleXMLElement is not properly initialized
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
--TEST--
2+
Incorrectly initialized SimpleXmlElement
3+
--FILE--
4+
<?php
5+
6+
class MySXE extends SimpleXMLElement {
7+
public function __construct() {
8+
/* yolo */
9+
}
10+
}
11+
12+
$sxe = new MySXE;
13+
try {
14+
var_dump($sxe->count());
15+
} catch (Error $e) {
16+
echo $e->getMessage(), "\n";
17+
}
18+
try {
19+
var_dump($sxe->xpath(''));
20+
} catch (Error $e) {
21+
echo $e->getMessage(), "\n";
22+
}
23+
try {
24+
var_dump($sxe->getDocNamespaces());
25+
} catch (Error $e) {
26+
echo $e->getMessage(), "\n";
27+
}
28+
try {
29+
var_dump($sxe->children());
30+
} catch (Error $e) {
31+
echo $e->getMessage(), "\n";
32+
}
33+
try {
34+
var_dump($sxe->attributes());
35+
} catch (Error $e) {
36+
echo $e->getMessage(), "\n";
37+
}
38+
try {
39+
var_dump($sxe->foo);
40+
} catch (Error $e) {
41+
echo $e->getMessage(), "\n";
42+
}
43+
44+
?>
45+
--EXPECT--
46+
SimpleXMLElement is not properly initialized
47+
SimpleXMLElement is not properly initialized
48+
SimpleXMLElement is not properly initialized
49+
SimpleXMLElement is not properly initialized
50+
SimpleXMLElement is not properly initialized
51+
SimpleXMLElement is not properly initialized

0 commit comments

Comments
 (0)