mirror of
https://github.com/php/php-src.git
synced 2025-08-15 21:48:51 +02:00
Merge branch 'PHP-8.3'
* PHP-8.3: Fix GH-15654: Signed integer overflow in ext/dom/nodelist.c
This commit is contained in:
commit
73b7993b0d
7 changed files with 45 additions and 11 deletions
2
NEWS
2
NEWS
|
@ -14,6 +14,8 @@ PHP NEWS
|
||||||
- DOM:
|
- DOM:
|
||||||
. Fixed bug GH-13988 (Storing DOMElement consume 4 times more memory in
|
. Fixed bug GH-13988 (Storing DOMElement consume 4 times more memory in
|
||||||
PHP 8.1 than in PHP 8.0). (nielsdos)
|
PHP 8.1 than in PHP 8.0). (nielsdos)
|
||||||
|
. Fixed bug GH-15654 (Signed integer overflow in ext/dom/nodelist.c).
|
||||||
|
(nielsdos)
|
||||||
|
|
||||||
- GD:
|
- GD:
|
||||||
. Added gdImageClone to bundled libgd. (David Carlier)
|
. Added gdImageClone to bundled libgd. (David Carlier)
|
||||||
|
|
|
@ -152,7 +152,7 @@ static xmlNodePtr dom_fetch_first_iteration_item(dom_nnodemap_object *objmap)
|
||||||
return dom_nodelist_iter_start_first_child(basep);
|
return dom_nodelist_iter_start_first_child(basep);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
int curindex = 0;
|
zend_long curindex = 0;
|
||||||
xmlNodePtr nodep = php_dom_first_child_of_container_node(basep);
|
xmlNodePtr nodep = php_dom_first_child_of_container_node(basep);
|
||||||
return dom_get_elements_by_tag_name_ns_raw(
|
return dom_get_elements_by_tag_name_ns_raw(
|
||||||
basep, nodep, objmap->ns, objmap->local, objmap->local_lower, &curindex, 0);
|
basep, nodep, objmap->ns, objmap->local, objmap->local_lower, &curindex, 0);
|
||||||
|
@ -209,7 +209,7 @@ static void php_dom_iterator_move_forward(zend_object_iterator *iter) /* {{{ */
|
||||||
/* We have a strong reference to the base node via baseobj_zv, this cannot become NULL */
|
/* We have a strong reference to the base node via baseobj_zv, this cannot become NULL */
|
||||||
ZEND_ASSERT(basenode != NULL);
|
ZEND_ASSERT(basenode != NULL);
|
||||||
|
|
||||||
int previndex;
|
zend_long previndex;
|
||||||
if (php_dom_is_cache_tag_stale_from_node(&iterator->cache_tag, basenode)) {
|
if (php_dom_is_cache_tag_stale_from_node(&iterator->cache_tag, basenode)) {
|
||||||
php_dom_mark_cache_tag_up_to_date_from_node(&iterator->cache_tag, basenode);
|
php_dom_mark_cache_tag_up_to_date_from_node(&iterator->cache_tag, basenode);
|
||||||
previndex = 0;
|
previndex = 0;
|
||||||
|
|
|
@ -46,8 +46,8 @@ static dom_named_item dom_html_collection_named_item(zend_string *key, zend_obje
|
||||||
/* 2. Return the first element in the collection for which at least one of the following is true: */
|
/* 2. Return the first element in the collection for which at least one of the following is true: */
|
||||||
xmlNodePtr basep = dom_object_get_node(objmap->baseobj);
|
xmlNodePtr basep = dom_object_get_node(objmap->baseobj);
|
||||||
if (basep != NULL) {
|
if (basep != NULL) {
|
||||||
int cur = 0;
|
zend_long cur = 0;
|
||||||
int next = cur; /* not +1, otherwise we skip the first candidate */
|
zend_long next = cur; /* not +1, otherwise we skip the first candidate */
|
||||||
xmlNodePtr candidate = basep->children;
|
xmlNodePtr candidate = basep->children;
|
||||||
while (candidate != NULL) {
|
while (candidate != NULL) {
|
||||||
candidate = dom_get_elements_by_tag_name_ns_raw(basep, candidate, objmap->ns, objmap->local, objmap->local_lower, &cur, next);
|
candidate = dom_get_elements_by_tag_name_ns_raw(basep, candidate, objmap->ns, objmap->local, objmap->local_lower, &cur, next);
|
||||||
|
|
|
@ -92,7 +92,7 @@ zend_long php_dom_get_nodelist_length(dom_object *obj)
|
||||||
reset_objmap_cache(objmap);
|
reset_objmap_cache(objmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
int count = 0;
|
zend_long count = 0;
|
||||||
if (objmap->nodetype == XML_ATTRIBUTE_NODE || objmap->nodetype == XML_ELEMENT_NODE) {
|
if (objmap->nodetype == XML_ATTRIBUTE_NODE || objmap->nodetype == XML_ELEMENT_NODE) {
|
||||||
xmlNodePtr curnode = dom_nodelist_iter_start_first_child(nodep);
|
xmlNodePtr curnode = dom_nodelist_iter_start_first_child(nodep);
|
||||||
if (curnode) {
|
if (curnode) {
|
||||||
|
@ -106,7 +106,7 @@ zend_long php_dom_get_nodelist_length(dom_object *obj)
|
||||||
xmlNodePtr basep = nodep;
|
xmlNodePtr basep = nodep;
|
||||||
nodep = php_dom_first_child_of_container_node(basep);
|
nodep = php_dom_first_child_of_container_node(basep);
|
||||||
dom_get_elements_by_tag_name_ns_raw(
|
dom_get_elements_by_tag_name_ns_raw(
|
||||||
basep, nodep, objmap->ns, objmap->local, objmap->local_lower, &count, INT_MAX - 1 /* because of <= */);
|
basep, nodep, objmap->ns, objmap->local, objmap->local_lower, &count, ZEND_LONG_MAX - 1 /* because of <= */);
|
||||||
}
|
}
|
||||||
|
|
||||||
objmap->cached_length = count;
|
objmap->cached_length = count;
|
||||||
|
@ -159,7 +159,7 @@ void php_dom_nodelist_get_item_into_zval(dom_nnodemap_object *objmap, zend_long
|
||||||
* TODO: in the future we could extend the logic of the node list such that backwards searches
|
* TODO: in the future we could extend the logic of the node list such that backwards searches
|
||||||
* are also possible. */
|
* are also possible. */
|
||||||
bool restart = true;
|
bool restart = true;
|
||||||
int relative_index = index;
|
zend_long relative_index = index;
|
||||||
if (index >= objmap->cached_obj_index && objmap->cached_obj && !php_dom_is_cache_tag_stale_from_node(&objmap->cache_tag, nodep)) {
|
if (index >= objmap->cached_obj_index && objmap->cached_obj && !php_dom_is_cache_tag_stale_from_node(&objmap->cache_tag, nodep)) {
|
||||||
xmlNodePtr cached_obj_xml_node = dom_object_get_node(objmap->cached_obj);
|
xmlNodePtr cached_obj_xml_node = dom_object_get_node(objmap->cached_obj);
|
||||||
|
|
||||||
|
@ -177,7 +177,7 @@ void php_dom_nodelist_get_item_into_zval(dom_nnodemap_object *objmap, zend_long
|
||||||
nodep = cached_obj_xml_node;
|
nodep = cached_obj_xml_node;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int count = 0;
|
zend_long count = 0;
|
||||||
if (objmap->nodetype == XML_ATTRIBUTE_NODE || objmap->nodetype == XML_ELEMENT_NODE) {
|
if (objmap->nodetype == XML_ATTRIBUTE_NODE || objmap->nodetype == XML_ELEMENT_NODE) {
|
||||||
if (restart) {
|
if (restart) {
|
||||||
nodep = dom_nodelist_iter_start_first_child(nodep);
|
nodep = dom_nodelist_iter_start_first_child(nodep);
|
||||||
|
|
|
@ -1855,7 +1855,7 @@ static bool dom_match_qualified_name_for_tag_name_equality(const xmlChar *local,
|
||||||
return dom_match_qualified_name_according_to_spec(local_to_use, nodep);
|
return dom_match_qualified_name_according_to_spec(local_to_use, nodep);
|
||||||
}
|
}
|
||||||
|
|
||||||
xmlNode *dom_get_elements_by_tag_name_ns_raw(xmlNodePtr basep, xmlNodePtr nodep, xmlChar *ns, xmlChar *local, xmlChar *local_lower, int *cur, int index) /* {{{ */
|
xmlNode *dom_get_elements_by_tag_name_ns_raw(xmlNodePtr basep, xmlNodePtr nodep, xmlChar *ns, xmlChar *local, xmlChar *local_lower, zend_long *cur, zend_long index) /* {{{ */
|
||||||
{
|
{
|
||||||
/* Can happen with detached document */
|
/* Can happen with detached document */
|
||||||
if (UNEXPECTED(nodep == NULL)) {
|
if (UNEXPECTED(nodep == NULL)) {
|
||||||
|
|
|
@ -87,7 +87,7 @@ typedef struct dom_nnodemap_object {
|
||||||
xmlChar *ns;
|
xmlChar *ns;
|
||||||
php_libxml_cache_tag cache_tag;
|
php_libxml_cache_tag cache_tag;
|
||||||
dom_object *cached_obj;
|
dom_object *cached_obj;
|
||||||
int cached_obj_index;
|
zend_long cached_obj_index;
|
||||||
bool free_local : 1;
|
bool free_local : 1;
|
||||||
bool free_ns : 1;
|
bool free_ns : 1;
|
||||||
} dom_nnodemap_object;
|
} dom_nnodemap_object;
|
||||||
|
@ -143,7 +143,7 @@ void dom_reconcile_ns_list(xmlDocPtr doc, xmlNodePtr nodep, xmlNodePtr last);
|
||||||
xmlNsPtr dom_get_nsdecl(xmlNode *node, xmlChar *localName);
|
xmlNsPtr dom_get_nsdecl(xmlNode *node, xmlChar *localName);
|
||||||
void php_dom_normalize_legacy(xmlNodePtr nodep);
|
void php_dom_normalize_legacy(xmlNodePtr nodep);
|
||||||
void php_dom_normalize_modern(xmlNodePtr nodep);
|
void php_dom_normalize_modern(xmlNodePtr nodep);
|
||||||
xmlNode *dom_get_elements_by_tag_name_ns_raw(xmlNodePtr basep, xmlNodePtr nodep, xmlChar *ns, xmlChar *local, xmlChar *local_lower, int *cur, int index);
|
xmlNode *dom_get_elements_by_tag_name_ns_raw(xmlNodePtr basep, xmlNodePtr nodep, xmlChar *ns, xmlChar *local, xmlChar *local_lower, zend_long *cur, zend_long index);
|
||||||
void php_dom_create_implementation(zval *retval, bool modern);
|
void php_dom_create_implementation(zval *retval, bool modern);
|
||||||
int dom_hierarchy(xmlNodePtr parent, xmlNodePtr child);
|
int dom_hierarchy(xmlNodePtr parent, xmlNodePtr child);
|
||||||
bool dom_has_feature(zend_string *feature, zend_string *version);
|
bool dom_has_feature(zend_string *feature, zend_string *version);
|
||||||
|
|
32
ext/dom/tests/gh15654.phpt
Normal file
32
ext/dom/tests/gh15654.phpt
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
--TEST--
|
||||||
|
GH-15654 (Signed integer overflow in ext/dom/nodelist.c)
|
||||||
|
--EXTENSIONS--
|
||||||
|
dom
|
||||||
|
--SKIPIF--
|
||||||
|
<?php
|
||||||
|
if (PHP_INT_SIZE != 8) die('skip 64-bit only');
|
||||||
|
?>
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
define("MAX_64Bit", 9223372036854775807);
|
||||||
|
define("MAX_32Bit", 2147483647);
|
||||||
|
define("MIN_64Bit", -9223372036854775807 - 1);
|
||||||
|
define("MIN_32Bit", -2147483647 - 1);
|
||||||
|
$longVals = array(
|
||||||
|
0, MAX_64Bit, MIN_64Bit, MAX_32Bit, MIN_32Bit, MAX_64Bit - MAX_32Bit, MIN_64Bit - MIN_32Bit,
|
||||||
|
);
|
||||||
|
$dom = new DOMDocument;
|
||||||
|
$dom->loadXML('<root><a/><b/><c/></root>');
|
||||||
|
$children = $dom->documentElement->childNodes;
|
||||||
|
foreach ($longVals as $value) {
|
||||||
|
var_dump($children[$value]?->nodeName);
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
--EXPECT--
|
||||||
|
string(1) "a"
|
||||||
|
NULL
|
||||||
|
NULL
|
||||||
|
NULL
|
||||||
|
NULL
|
||||||
|
NULL
|
||||||
|
NULL
|
Loading…
Add table
Add a link
Reference in a new issue