Fix GH-14638: null dereference after XML parsing failure.

object document is null if the parsing had failed prior to cast to
string.
This commit is contained in:
David Carlier 2024-06-23 15:06:35 +01:00
parent 98cb0be17d
commit 2edf12e87f
No known key found for this signature in database
GPG key ID: CEF290BB40D2086B
3 changed files with 61 additions and 24 deletions

4
NEWS
View file

@ -31,6 +31,10 @@ PHP NEWS
- Shmop:
. Fixed bug GH-14537 (shmop Windows 11 crashes the process). (nielsdos)
- SimpleXML:
. Fixed bug GH-14638 (null dereference after XML parsing failure).
(David Carlier)
04 Jul 2024, PHP 8.2.21
- Core:

View file

@ -1502,6 +1502,35 @@ static void sxe_add_namespaces(php_sxe_object *sxe, xmlNodePtr node, bool recurs
}
} /* }}} */
static inline void sxe_object_free_iterxpath(php_sxe_object *sxe)
{
if (!Z_ISUNDEF(sxe->iter.data)) {
zval_ptr_dtor(&sxe->iter.data);
ZVAL_UNDEF(&sxe->iter.data);
}
if (sxe->iter.name) {
efree(sxe->iter.name);
sxe->iter.name = NULL;
}
if (sxe->iter.nsprefix) {
efree(sxe->iter.nsprefix);
sxe->iter.nsprefix = NULL;
}
if (!Z_ISUNDEF(sxe->tmp)) {
zval_ptr_dtor(&sxe->tmp);
ZVAL_UNDEF(&sxe->tmp);
}
php_libxml_node_decrement_resource((php_libxml_node_object *)sxe);
if (sxe->xpath) {
xmlXPathFreeContext(sxe->xpath);
sxe->xpath = NULL;
}
}
/* {{{ Return all namespaces in use */
PHP_METHOD(SimpleXMLElement, getNamespaces)
{
@ -2156,29 +2185,7 @@ static void sxe_object_free_storage(zend_object *object)
zend_object_std_dtor(&sxe->zo);
if (!Z_ISUNDEF(sxe->iter.data)) {
zval_ptr_dtor(&sxe->iter.data);
ZVAL_UNDEF(&sxe->iter.data);
}
if (sxe->iter.name) {
efree(sxe->iter.name);
sxe->iter.name = NULL;
}
if (sxe->iter.nsprefix) {
efree(sxe->iter.nsprefix);
sxe->iter.nsprefix = NULL;
}
if (!Z_ISUNDEF(sxe->tmp)) {
zval_ptr_dtor(&sxe->tmp);
ZVAL_UNDEF(&sxe->tmp);
}
php_libxml_node_decrement_resource((php_libxml_node_object *)sxe);
if (sxe->xpath) {
xmlXPathFreeContext(sxe->xpath);
}
sxe_object_free_iterxpath(sxe);
if (sxe->properties) {
zend_hash_destroy(sxe->properties);
@ -2378,11 +2385,12 @@ PHP_METHOD(SimpleXMLElement, __construct)
PHP_LIBXML_RESTORE_GLOBALS(read_file_or_memory);
if (!docp) {
((php_libxml_node_object *)sxe)->document = NULL;
zend_throw_exception(zend_ce_exception, "String could not be parsed as XML", 0);
RETURN_THROWS();
}
sxe_object_free_iterxpath(sxe);
sxe->iter.nsprefix = ns_len ? (xmlChar*)estrdup(ns) : NULL;
sxe->iter.isprefix = isprefix;
php_libxml_increment_doc_ref((php_libxml_node_object *)sxe, docp);

View file

@ -0,0 +1,25 @@
--TEST--
GH-14638: null pointer dereference on object cast __toString after failed XML parsing
--EXTENSIONS--
simplexml
--CREDITS--
YuanchengJiang
--FILE--
<?php
$xml = '<?xml version="1.0" encoding="utf-8" ?>
<test>
</test>';
$root = simplexml_load_string($xml);
try {
$root->__construct("malformed");
} catch (Exception $e) {
// Intentionally empty
}
echo $root;
?>
--EXPECTF--
Warning: SimpleXMLElement::__construct(): Entity: line 1: parser error : Start tag expected, '<' not found in %s on line %d
Warning: SimpleXMLElement::__construct(): malformed in %s on line %d
Warning: SimpleXMLElement::__construct(): ^ in %s on line %d