diff options
author | Tjerk Meesters <datibbaw@php.net> | 2014-10-09 23:32:19 +0800 |
---|---|---|
committer | Tjerk Meesters <datibbaw@php.net> | 2014-10-09 23:32:19 +0800 |
commit | 0a50b250b2538c3640edb7d8ff07c85472823041 (patch) | |
tree | 663b25da2f5643d7d75c49a032aab0398d6dd4bf | |
parent | 2f099478a3c5509e4063002b3256bde380739e3d (diff) | |
parent | 59f39dea66f8de4de240eb01b4553644fdc5b8bd (diff) | |
download | php-git-0a50b250b2538c3640edb7d8ff07c85472823041.tar.gz |
Merge branch 'PHP-5.6'
* PHP-5.6:
Refactored DOMNodeList array dereferencing implementation
Conflicts:
ext/dom/nodelist.c
ext/dom/php_dom.c
-rw-r--r-- | ext/dom/nodelist.c | 68 | ||||
-rw-r--r-- | ext/dom/php_dom.c | 71 | ||||
-rw-r--r-- | ext/dom/php_dom.h | 1 | ||||
-rw-r--r-- | ext/dom/tests/bug67949.phpt | 53 |
4 files changed, 92 insertions, 101 deletions
diff --git a/ext/dom/nodelist.c b/ext/dom/nodelist.c index 223960c5bc..15071739d2 100644 --- a/ext/dom/nodelist.c +++ b/ext/dom/nodelist.c @@ -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); + } + } } } } diff --git a/ext/dom/php_dom.c b/ext/dom/php_dom.c index cfe6b1232b..71c06612db 100644 --- a/ext/dom/php_dom.c +++ b/ext/dom/php_dom.c @@ -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) /* {{{ */ +zval *dom_nodelist_read_dimension(zval *object, zval *offset, int type, 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); - } - } - } + zval offset_copy; - if (rv != NULL && itemnode != NULL) { - if (*itemnode) { - ret = 1; - } + if (!offset) { + return NULL; } - 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_COPY(&offset_copy, offset); + convert_to_long(&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); - } - } + 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); + + if (Z_LVAL(offset_copy) < 0) { + return 0; + } - return dom_nodelist_fetch_dimension(NULL, member, objmap, NULL TSRMLS_CC); + 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 */ diff --git a/ext/dom/php_dom.h b/ext/dom/php_dom.h index 9f8023f67b..02eb2d9509 100644 --- a/ext/dom/php_dom.h +++ b/ext/dom/php_dom.h @@ -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); \ diff --git a/ext/dom/tests/bug67949.phpt b/ext/dom/tests/bug67949.phpt index b12dc81d1d..fc29881ca7 100644 --- a/ext/dom/tests/bug67949.phpt +++ b/ext/dom/tests/bug67949.phpt @@ -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-- +$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) -bool(false) +string(4) "test" +testing read_dimension with null offset +NULL +testing attribute access +string(4) "href" +==DONE== |