diff --git a/NEWS b/NEWS index 088501d1027..bb597215fb6 100644 --- a/NEWS +++ b/NEWS @@ -20,6 +20,8 @@ PHP NEWS - DOM: . Fixed bug GH-15551 (Segmentation fault (access null pointer) in ext/dom/xml_common.h). (nielsdos) + . Fixed bug GH-15654 (Signed integer overflow in ext/dom/nodelist.c). + (nielsdos) - MySQLnd: . Fixed bug GH-15432 (Heap corruption when querying a vector). (cmb, diff --git a/ext/dom/dom_iterators.c b/ext/dom/dom_iterators.c index dc4c83a7696..adc5835f9d8 100644 --- a/ext/dom/dom_iterators.c +++ b/ext/dom/dom_iterators.c @@ -179,7 +179,7 @@ static void php_dom_iterator_move_forward(zend_object_iterator *iter) /* {{{ */ dom_object *intern; dom_object *nnmap; dom_nnodemap_object *objmap; - int previndex; + zend_long previndex; HashTable *nodeht; zval *entry; bool do_curobj_undef = 1; @@ -269,7 +269,7 @@ zend_object_iterator *php_dom_get_iterator(zend_class_entry *ce, zval *object, i dom_object *intern; dom_nnodemap_object *objmap; xmlNodePtr curnode=NULL; - int curindex = 0; + zend_long curindex = 0; HashTable *nodeht; zval *entry; php_dom_iterator *iterator; diff --git a/ext/dom/nodelist.c b/ext/dom/nodelist.c index bb58161f16e..34767e048b5 100644 --- a/ext/dom/nodelist.c +++ b/ext/dom/nodelist.c @@ -91,7 +91,7 @@ int php_dom_get_nodelist_length(dom_object *obj) reset_objmap_cache(objmap); } - int count = 0; + zend_long count = 0; if (objmap->nodetype == XML_ATTRIBUTE_NODE || objmap->nodetype == XML_ELEMENT_NODE) { xmlNodePtr curnode = dom_nodelist_iter_start_first_child(nodep); if (curnode) { @@ -109,7 +109,7 @@ int php_dom_get_nodelist_length(dom_object *obj) nodep = nodep->children; } dom_get_elements_by_tag_name_ns_raw( - basep, nodep, (char *) objmap->ns, (char *) objmap->local, &count, INT_MAX - 1 /* because of <= */); + basep, nodep, (char *) objmap->ns, (char *) objmap->local, &count, ZEND_LONG_MAX - 1 /* because of <= */); } objmap->cached_length = count; @@ -174,7 +174,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 * are also possible. */ 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)) { xmlNodePtr cached_obj_xml_node = dom_object_get_node(objmap->cached_obj); @@ -192,7 +192,7 @@ void php_dom_nodelist_get_item_into_zval(dom_nnodemap_object *objmap, zend_long nodep = cached_obj_xml_node; } } - int count = 0; + zend_long count = 0; if (objmap->nodetype == XML_ATTRIBUTE_NODE || objmap->nodetype == XML_ELEMENT_NODE) { if (restart) { nodep = dom_nodelist_iter_start_first_child(nodep); diff --git a/ext/dom/php_dom.c b/ext/dom/php_dom.c index ff598f1ee54..5c7aacefba5 100644 --- a/ext/dom/php_dom.c +++ b/ext/dom/php_dom.c @@ -1334,7 +1334,7 @@ bool dom_has_feature(zend_string *feature, zend_string *version) } /* }}} end dom_has_feature */ -xmlNode *dom_get_elements_by_tag_name_ns_raw(xmlNodePtr basep, xmlNodePtr nodep, char *ns, char *local, int *cur, int index) /* {{{ */ +xmlNode *dom_get_elements_by_tag_name_ns_raw(xmlNodePtr basep, xmlNodePtr nodep, char *ns, char *local, zend_long *cur, zend_long index) /* {{{ */ { /* Can happen with detached document */ if (UNEXPECTED(nodep == NULL)) { diff --git a/ext/dom/php_dom.h b/ext/dom/php_dom.h index 86e6b131545..c5c888a64c5 100644 --- a/ext/dom/php_dom.h +++ b/ext/dom/php_dom.h @@ -88,7 +88,7 @@ typedef struct _dom_nnodemap_object { xmlChar *ns; php_libxml_cache_tag cache_tag; dom_object *cached_obj; - int cached_obj_index; + zend_long cached_obj_index; bool free_local : 1; bool free_ns : 1; } dom_nnodemap_object; @@ -133,7 +133,7 @@ void dom_reconcile_ns(xmlDocPtr doc, xmlNodePtr nodep); void dom_reconcile_ns_list(xmlDocPtr doc, xmlNodePtr nodep, xmlNodePtr last); xmlNsPtr dom_get_nsdecl(xmlNode *node, xmlChar *localName); void dom_normalize (xmlNodePtr nodep); -xmlNode *dom_get_elements_by_tag_name_ns_raw(xmlNodePtr basep, xmlNodePtr nodep, char *ns, char *local, int *cur, int index); +xmlNode *dom_get_elements_by_tag_name_ns_raw(xmlNodePtr basep, xmlNodePtr nodep, char *ns, char *local, zend_long *cur, zend_long index); void php_dom_create_implementation(zval *retval); int dom_hierarchy(xmlNodePtr parent, xmlNodePtr child); bool dom_has_feature(zend_string *feature, zend_string *version); diff --git a/ext/dom/tests/gh15654.phpt b/ext/dom/tests/gh15654.phpt new file mode 100644 index 00000000000..ed4b0f34aff --- /dev/null +++ b/ext/dom/tests/gh15654.phpt @@ -0,0 +1,32 @@ +--TEST-- +GH-15654 (Signed integer overflow in ext/dom/nodelist.c) +--EXTENSIONS-- +dom +--SKIPIF-- + +--FILE-- +loadXML(''); +$children = $dom->documentElement->childNodes; +foreach ($longVals as $value) { + var_dump($children[$value]?->nodeName); +} +?> +--EXPECT-- +string(1) "a" +NULL +NULL +NULL +NULL +NULL +NULL