mirror of
https://github.com/php/php-src.git
synced 2024-12-24 01:09:58 +08:00
Merge branch 'PHP-5.6'
* PHP-5.6: Refactored DOMNodeList array dereferencing implementation Conflicts: ext/dom/nodelist.c ext/dom/php_dom.c
This commit is contained in:
commit
0a50b250b2
@ -98,47 +98,6 @@ int dom_nodelist_length_read(dom_object *obj, zval *retval TSRMLS_DC)
|
||||
|
||||
/* }}} */
|
||||
|
||||
xmlNodePtr dom_nodelist_xml_item(dom_nnodemap_object *objmap, long index) /* {{{ */
|
||||
{
|
||||
xmlNodePtr itemnode = NULL;
|
||||
|
||||
if (objmap->nodetype == XML_ENTITY_NODE) {
|
||||
itemnode = php_dom_libxml_hash_iter(objmap->ht, index);
|
||||
} else {
|
||||
itemnode = php_dom_libxml_notation_iter(objmap->ht, index);
|
||||
}
|
||||
|
||||
return itemnode;
|
||||
} /* }}} end dom_nodelist_xml_item */
|
||||
|
||||
xmlNodePtr dom_nodelist_baseobj_item(dom_nnodemap_object *objmap, long index) /* {{{ */
|
||||
{
|
||||
xmlNodePtr itemnode = NULL;
|
||||
xmlNodePtr nodep, curnode;
|
||||
int count = 0;
|
||||
|
||||
nodep = dom_object_get_node(objmap->baseobj);
|
||||
if (nodep) {
|
||||
if (objmap->nodetype == XML_ATTRIBUTE_NODE || objmap->nodetype == XML_ELEMENT_NODE) {
|
||||
curnode = nodep->children;
|
||||
while (count < index && curnode != NULL) {
|
||||
count++;
|
||||
curnode = curnode->next;
|
||||
}
|
||||
itemnode = curnode;
|
||||
} else {
|
||||
if (nodep->type == XML_DOCUMENT_NODE || nodep->type == XML_HTML_DOCUMENT_NODE) {
|
||||
nodep = xmlDocGetRootElement((xmlDoc *) nodep);
|
||||
} else {
|
||||
nodep = nodep->children;
|
||||
}
|
||||
itemnode = dom_get_elements_by_tag_name_ns_raw(nodep, (char *) objmap->ns, (char *) objmap->local, &count, index);
|
||||
}
|
||||
}
|
||||
|
||||
return itemnode;
|
||||
} /* }}} end dom_nodelist_baseobj_item */
|
||||
|
||||
/* {{{ proto DOMNode dom_nodelist_item(int index);
|
||||
URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-844377136
|
||||
Since:
|
||||
@ -152,6 +111,8 @@ PHP_FUNCTION(dom_nodelist_item)
|
||||
xmlNodePtr itemnode = NULL;
|
||||
|
||||
dom_nnodemap_object *objmap;
|
||||
xmlNodePtr nodep, curnode;
|
||||
int count = 0;
|
||||
|
||||
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ol", &id, dom_nodelist_class_entry, &index) == FAILURE) {
|
||||
return;
|
||||
@ -163,7 +124,11 @@ PHP_FUNCTION(dom_nodelist_item)
|
||||
objmap = (dom_nnodemap_object *)intern->ptr;
|
||||
if (objmap != NULL) {
|
||||
if (objmap->ht) {
|
||||
itemnode = dom_nodelist_xml_item(objmap, index);
|
||||
if (objmap->nodetype == XML_ENTITY_NODE) {
|
||||
itemnode = php_dom_libxml_hash_iter(objmap->ht, index);
|
||||
} else {
|
||||
itemnode = php_dom_libxml_notation_iter(objmap->ht, index);
|
||||
}
|
||||
} else {
|
||||
if (objmap->nodetype == DOM_NODESET) {
|
||||
HashTable *nodeht = HASH_OF(&objmap->baseobj_zv);
|
||||
@ -173,7 +138,24 @@ PHP_FUNCTION(dom_nodelist_item)
|
||||
return;
|
||||
}
|
||||
} else if (objmap->baseobj) {
|
||||
itemnode = dom_nodelist_baseobj_item(objmap, index);
|
||||
nodep = dom_object_get_node(objmap->baseobj);
|
||||
if (nodep) {
|
||||
if (objmap->nodetype == XML_ATTRIBUTE_NODE || objmap->nodetype == XML_ELEMENT_NODE) {
|
||||
curnode = nodep->children;
|
||||
while (count < index && curnode != NULL) {
|
||||
count++;
|
||||
curnode = curnode->next;
|
||||
}
|
||||
itemnode = curnode;
|
||||
} else {
|
||||
if (nodep->type == XML_DOCUMENT_NODE || nodep->type == XML_HTML_DOCUMENT_NODE) {
|
||||
nodep = xmlDocGetRootElement((xmlDoc *) nodep);
|
||||
} else {
|
||||
nodep = nodep->children;
|
||||
}
|
||||
itemnode = dom_get_elements_by_tag_name_ns_raw(nodep, objmap->ns, objmap->local, &count, index);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1544,70 +1544,39 @@ xmlNsPtr dom_get_nsdecl(xmlNode *node, xmlChar *localName) {
|
||||
}
|
||||
/* }}} end dom_get_nsdecl */
|
||||
|
||||
static int dom_nodelist_fetch_dimension(xmlNodePtr *itemnode, zval *offset, dom_nnodemap_object *objmap, zval *rv TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
long index = zval_get_long(offset);
|
||||
HashTable *nodeht;
|
||||
int ret = 0;
|
||||
|
||||
if (objmap->ht) {
|
||||
*itemnode = dom_nodelist_xml_item(objmap, index);
|
||||
} else {
|
||||
if (objmap->nodetype == DOM_NODESET) {
|
||||
nodeht = HASH_OF(&objmap->baseobj_zv);
|
||||
zval *entry = zend_hash_index_find(nodeht, index);
|
||||
if (entry) {
|
||||
if (itemnode != NULL && rv != NULL) {
|
||||
/* Passed by read_dimension */
|
||||
ZVAL_COPY(rv, entry);
|
||||
}
|
||||
ret = 1;
|
||||
}
|
||||
} else if (objmap->baseobj) {
|
||||
if (itemnode == NULL && rv == NULL) {
|
||||
/* Passed by has_dimension */
|
||||
if (dom_nodelist_baseobj_item(objmap, index)) {
|
||||
ret = 1;
|
||||
}
|
||||
} else {
|
||||
*itemnode = dom_nodelist_baseobj_item(objmap, index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (rv != NULL && itemnode != NULL) {
|
||||
if (*itemnode) {
|
||||
ret = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
} /* }}} end dom_nodelist_fetch_dimension */
|
||||
|
||||
zval *dom_nodelist_read_dimension(zval *object, zval *offset, int type, zval *rv TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
dom_object *intern = Z_DOMOBJ_P(object);
|
||||
xmlNodePtr itemnode = NULL;
|
||||
dom_nnodemap_object *objmap = (dom_nnodemap_object *)intern->ptr;
|
||||
zval offset_copy;
|
||||
|
||||
if (dom_nodelist_fetch_dimension(&itemnode, offset, objmap, rv TSRMLS_CC)) {
|
||||
if (itemnode) {
|
||||
php_dom_create_object(itemnode, rv, objmap->baseobj TSRMLS_CC);
|
||||
}
|
||||
if (!offset) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ZVAL_COPY(&offset_copy, offset);
|
||||
convert_to_long(&offset_copy);
|
||||
|
||||
zend_call_method_with_1_params(object, Z_OBJCE_P(object), NULL, "item", rv, &offset_copy);
|
||||
|
||||
return rv;
|
||||
} /* }}} end dom_nodelist_read_dimension */
|
||||
|
||||
int dom_nodelist_has_dimension(zval *object, zval *member, int check_empty TSRMLS_DC)
|
||||
{
|
||||
dom_object *intern;
|
||||
dom_nnodemap_object *objmap;
|
||||
zval *length, offset_copy;
|
||||
int ret;
|
||||
|
||||
intern = Z_DOMOBJ_P(object);
|
||||
objmap = (dom_nnodemap_object *)intern->ptr;
|
||||
ZVAL_COPY(&offset_copy, member);
|
||||
convert_to_long(&offset_copy);
|
||||
|
||||
return dom_nodelist_fetch_dimension(NULL, member, objmap, NULL TSRMLS_CC);
|
||||
if (Z_LVAL(offset_copy) < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
length = zend_read_property(Z_OBJCE_P(object), object, "length", sizeof("length") - 1, 0 TSRMLS_CC);
|
||||
|
||||
ret = Z_LVAL(offset_copy) < Z_LVAL_P(length);
|
||||
|
||||
return ret;
|
||||
} /* }}} end dom_nodelist_has_dimension */
|
||||
|
||||
#endif /* HAVE_DOM */
|
||||
|
@ -128,7 +128,6 @@ zend_object_iterator *php_dom_get_iterator(zend_class_entry *ce, zval *object, i
|
||||
int dom_set_doc_classmap(php_libxml_ref_obj *document, zend_class_entry *basece, zend_class_entry *ce TSRMLS_DC);
|
||||
zval *dom_nodelist_read_dimension(zval *object, zval *offset, int type, zval *rv TSRMLS_DC);
|
||||
int dom_nodelist_has_dimension(zval *object, zval *member, int check_empty TSRMLS_DC);
|
||||
static int dom_nodelist_fetch_dimension(xmlNodePtr *itemnode, zval *offset, dom_nnodemap_object *objmap, zval *rv TSRMLS_DC);
|
||||
|
||||
#define REGISTER_DOM_CLASS(ce, name, parent_ce, funcs, entry) \
|
||||
INIT_CLASS_ENTRY(ce, name, funcs); \
|
||||
|
@ -5,16 +5,57 @@ Bug #67949: DOMNodeList elements should be accessible through array notation
|
||||
|
||||
$html = <<<HTML
|
||||
<div>data</div>
|
||||
<a href="test">hello world</a>
|
||||
HTML;
|
||||
$doc = new DOMDocument;
|
||||
$doc->loadHTML($html);
|
||||
var_dump($doc->getElementsByTagName('div')[0]->textContent);
|
||||
var_dump($doc->getElementsByTagName('div')['test']->textContent); // testing that weak casting works
|
||||
var_dump(isset($doc->getElementsByTagName('div')[0]));
|
||||
var_dump(isset($doc->getElementsByTagName('div')[1]));
|
||||
|
||||
--EXPECT--
|
||||
string(4) "data"
|
||||
string(4) "data"
|
||||
$nodes = $doc->getElementsByTagName('div');
|
||||
|
||||
echo "testing has_dimension\n";
|
||||
var_dump(isset($nodes[0]));
|
||||
var_dump(isset($nodes[1]));
|
||||
var_dump(isset($nodes[-1]));
|
||||
|
||||
echo "testing property access\n";
|
||||
var_dump($nodes[0]->textContent);
|
||||
var_dump($nodes[1]->textContent);
|
||||
|
||||
echo "testing offset not a long\n";
|
||||
$offset = 'test';
|
||||
var_dump($offset);
|
||||
var_dump($nodes[$offset]->textContent);
|
||||
var_dump($offset);
|
||||
var_dump(isset($nodes[$offset]));
|
||||
var_dump($offset);
|
||||
|
||||
echo "testing read_dimension with null offset\n";
|
||||
var_dump($nodes[][] = 1);
|
||||
|
||||
echo "testing attribute access\n";
|
||||
$anchor = $doc->getElementsByTagName('a')[0];
|
||||
var_dump($anchor->attributes[0]->name);
|
||||
|
||||
echo "==DONE==\n";
|
||||
|
||||
--EXPECTF--
|
||||
testing has_dimension
|
||||
bool(true)
|
||||
bool(false)
|
||||
bool(false)
|
||||
testing property access
|
||||
string(4) "data"
|
||||
|
||||
Notice: Trying to get property of non-object in %s on line %d
|
||||
NULL
|
||||
testing offset not a long
|
||||
string(4) "test"
|
||||
string(4) "data"
|
||||
string(4) "test"
|
||||
bool(true)
|
||||
string(4) "test"
|
||||
testing read_dimension with null offset
|
||||
NULL
|
||||
testing attribute access
|
||||
string(4) "href"
|
||||
==DONE==
|
||||
|
Loading…
Reference in New Issue
Block a user