Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #80332: Completely broken array access functionality with DOMNamedNodeMap #11468

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
122 changes: 63 additions & 59 deletions ext/dom/namednodemap.c
Expand Up @@ -31,7 +31,7 @@
* Since:
*/

static int get_namednodemap_length(dom_object *obj)
int php_dom_get_namednodemap_length(dom_object *obj)
{
dom_nnodemap_object *objmap = (dom_nnodemap_object *) obj->ptr;
if (!objmap) {
Expand Down Expand Up @@ -65,95 +65,74 @@ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-
*/
int dom_namednodemap_length_read(dom_object *obj, zval *retval)
{
ZVAL_LONG(retval, get_namednodemap_length(obj));
ZVAL_LONG(retval, php_dom_get_namednodemap_length(obj));
return SUCCESS;
}

/* }}} */

/* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1074577549
Since:
*/
PHP_METHOD(DOMNamedNodeMap, getNamedItem)
xmlNodePtr php_dom_named_node_map_get_named_item(dom_nnodemap_object *objmap, const char *named, bool may_transform)
{
zval *id;
int ret;
size_t namedlen=0;
dom_object *intern;
xmlNodePtr itemnode = NULL;
char *named;

dom_nnodemap_object *objmap;
xmlNodePtr nodep;
xmlNotation *notep = NULL;

id = ZEND_THIS;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &named, &namedlen) == FAILURE) {
RETURN_THROWS();
}

intern = Z_DOMOBJ_P(id);

objmap = (dom_nnodemap_object *)intern->ptr;

if (objmap != NULL) {
if ((objmap->nodetype == XML_NOTATION_NODE) ||
objmap->nodetype == XML_ENTITY_NODE) {
if (objmap->ht) {
if (objmap->nodetype == XML_ENTITY_NODE) {
itemnode = (xmlNodePtr)xmlHashLookup(objmap->ht, (xmlChar *) named);
itemnode = (xmlNodePtr)xmlHashLookup(objmap->ht, (const xmlChar *) named);
} else {
notep = (xmlNotation *)xmlHashLookup(objmap->ht, (xmlChar *) named);
xmlNotationPtr notep = xmlHashLookup(objmap->ht, (const xmlChar *) named);
if (notep) {
itemnode = create_notation(notep->name, notep->PublicID, notep->SystemID);
if (may_transform) {
itemnode = create_notation(notep->name, notep->PublicID, notep->SystemID);
} else {
itemnode = (xmlNodePtr) notep;
}
}
}
}
} else {
nodep = dom_object_get_node(objmap->baseobj);
xmlNodePtr nodep = dom_object_get_node(objmap->baseobj);
if (nodep) {
itemnode = (xmlNodePtr)xmlHasProp(nodep, (xmlChar *) named);
itemnode = (xmlNodePtr)xmlHasProp(nodep, (const xmlChar *) named);
}
}
}
return itemnode;
}

void php_dom_named_node_map_get_named_item_into_zval(dom_nnodemap_object *objmap, const char *named, zval *return_value)
{
int ret;
xmlNodePtr itemnode = php_dom_named_node_map_get_named_item(objmap, named, true);
if (itemnode) {
DOM_RET_OBJ(itemnode, &ret, objmap->baseobj);
return;
} else {
RETVAL_NULL();
RETURN_NULL();
}
}
/* }}} end dom_namednodemap_get_named_item */

/* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-349467F9
/* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1074577549
Since:
*/
PHP_METHOD(DOMNamedNodeMap, item)
PHP_METHOD(DOMNamedNodeMap, getNamedItem)
{
zval *id;
zend_long index;
int ret;
dom_object *intern;
xmlNodePtr itemnode = NULL;

dom_nnodemap_object *objmap;
xmlNodePtr nodep, curnode;
int count;
size_t namedlen;
char *named;

id = ZEND_THIS;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &index) == FAILURE) {
RETURN_THROWS();
}
if (index < 0 || ZEND_LONG_INT_OVFL(index)) {
zend_argument_value_error(1, "must be between 0 and %d", INT_MAX);
if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &named, &namedlen) == FAILURE) {
RETURN_THROWS();
}

intern = Z_DOMOBJ_P(id);

objmap = (dom_nnodemap_object *)intern->ptr;
zval *id = ZEND_THIS;
dom_nnodemap_object *objmap = Z_DOMOBJ_P(id)->ptr;
php_dom_named_node_map_get_named_item_into_zval(objmap, named, return_value);
}
/* }}} end dom_namednodemap_get_named_item */

xmlNodePtr php_dom_named_node_map_get_item(dom_nnodemap_object *objmap, zend_long index)
{
xmlNodePtr itemnode = NULL;
if (objmap != NULL) {
if ((objmap->nodetype == XML_NOTATION_NODE) ||
objmap->nodetype == XML_ENTITY_NODE) {
Expand All @@ -165,10 +144,10 @@ PHP_METHOD(DOMNamedNodeMap, item)
}
}
} else {
nodep = dom_object_get_node(objmap->baseobj);
xmlNodePtr nodep = dom_object_get_node(objmap->baseobj);
if (nodep) {
curnode = (xmlNodePtr)nodep->properties;
count = 0;
xmlNodePtr curnode = (xmlNodePtr)nodep->properties;
zend_long count = 0;
while (count < index && curnode != NULL) {
count++;
curnode = (xmlNodePtr)curnode->next;
Expand All @@ -177,13 +156,38 @@ PHP_METHOD(DOMNamedNodeMap, item)
}
}
}
return itemnode;
}

void php_dom_named_node_map_get_item_into_zval(dom_nnodemap_object *objmap, zend_long index, zval *return_value)
{
int ret;
xmlNodePtr itemnode = php_dom_named_node_map_get_item(objmap, index);
if (itemnode) {
DOM_RET_OBJ(itemnode, &ret, objmap->baseobj);
return;
} else {
RETURN_NULL();
}
}

/* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-349467F9
Since:
*/
PHP_METHOD(DOMNamedNodeMap, item)
{
zend_long index;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &index) == FAILURE) {
RETURN_THROWS();
}
if (index < 0 || ZEND_LONG_INT_OVFL(index)) {
zend_argument_value_error(1, "must be between 0 and %d", INT_MAX);
RETURN_THROWS();
}

RETVAL_NULL();
zval *id = ZEND_THIS;
dom_object *intern = Z_DOMOBJ_P(id);
dom_nnodemap_object *objmap = intern->ptr;
php_dom_named_node_map_get_item_into_zval(objmap, index, return_value);
}
/* }}} end dom_namednodemap_item */

Expand Down Expand Up @@ -254,7 +258,7 @@ PHP_METHOD(DOMNamedNodeMap, count)
}

intern = Z_DOMOBJ_P(id);
RETURN_LONG(get_namednodemap_length(intern));
RETURN_LONG(php_dom_get_namednodemap_length(intern));
}
/* }}} end dom_namednodemap_count */

Expand Down
50 changes: 23 additions & 27 deletions ext/dom/nodelist.c
Expand Up @@ -31,7 +31,7 @@
* Since:
*/

static int get_nodelist_length(dom_object *obj)
int php_dom_get_nodelist_length(dom_object *obj)
{
dom_nnodemap_object *objmap = (dom_nnodemap_object *) obj->ptr;
if (!objmap) {
Expand Down Expand Up @@ -82,7 +82,7 @@ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-20
*/
int dom_nodelist_length_read(dom_object *obj, zval *retval)
{
ZVAL_LONG(retval, get_nodelist_length(obj));
ZVAL_LONG(retval, php_dom_get_nodelist_length(obj));
return SUCCESS;
}

Expand All @@ -99,36 +99,15 @@ PHP_METHOD(DOMNodeList, count)
}

intern = Z_DOMOBJ_P(id);
RETURN_LONG(get_nodelist_length(intern));
RETURN_LONG(php_dom_get_nodelist_length(intern));
}
/* }}} end dom_nodelist_count */

/* }}} */

/* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-844377136
Since:
*/
PHP_METHOD(DOMNodeList, item)
void php_dom_nodelist_get_item_into_zval(dom_nnodemap_object *objmap, zend_long index, zval *return_value)
{
zval *id;
zend_long index;
int ret;
dom_object *intern;
xmlNodePtr itemnode = NULL;

dom_nnodemap_object *objmap;
xmlNodePtr nodep, curnode;
int count = 0;

id = ZEND_THIS;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &index) == FAILURE) {
RETURN_THROWS();
}

if (index >= 0) {
intern = Z_DOMOBJ_P(id);

objmap = (dom_nnodemap_object *)intern->ptr;
if (objmap != NULL) {
if (objmap->ht) {
if (objmap->nodetype == XML_ENTITY_NODE) {
Expand All @@ -145,10 +124,11 @@ PHP_METHOD(DOMNodeList, item)
return;
}
} else if (objmap->baseobj) {
nodep = dom_object_get_node(objmap->baseobj);
xmlNodePtr nodep = dom_object_get_node(objmap->baseobj);
if (nodep) {
int count = 0;
if (objmap->nodetype == XML_ATTRIBUTE_NODE || objmap->nodetype == XML_ELEMENT_NODE) {
curnode = nodep->children;
xmlNodePtr curnode = nodep->children;
while (count < index && curnode != NULL) {
count++;
curnode = curnode->next;
Expand All @@ -175,6 +155,22 @@ PHP_METHOD(DOMNodeList, item)

RETVAL_NULL();
}

/* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-844377136
Since:
*/
PHP_METHOD(DOMNodeList, item)
{
zend_long index;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &index) == FAILURE) {
RETURN_THROWS();
}

zval *id = ZEND_THIS;
dom_object *intern = Z_DOMOBJ_P(id);
dom_nnodemap_object *objmap = intern->ptr;
php_dom_nodelist_get_item_into_zval(objmap, index, return_value);
}
/* }}} end dom_nodelist_item */

ZEND_METHOD(DOMNodeList, getIterator)
Expand Down