diff options
author | Rob Richards <rrichards@php.net> | 2004-01-07 15:33:25 +0000 |
---|---|---|
committer | Rob Richards <rrichards@php.net> | 2004-01-07 15:33:25 +0000 |
commit | 6e65e1d82106b9aca0a2dcf498df54ffccae7168 (patch) | |
tree | 8f1006fba643d54dba653cdc06695e34a81bbb0d /ext/dom/document.c | |
parent | ee8f019b68b052eca8f32bf8573490f458f61160 (diff) | |
download | php-git-6e65e1d82106b9aca0a2dcf498df54ffccae7168.tar.gz |
Fix bug #26815 (foreach (DOM) childnodes causes error using Xinclude)
update xinclude test
Diffstat (limited to 'ext/dom/document.c')
-rw-r--r-- | ext/dom/document.c | 48 |
1 files changed, 47 insertions, 1 deletions
diff --git a/ext/dom/document.c b/ext/dom/document.c index 914b659f87..7d3c25873e 100644 --- a/ext/dom/document.c +++ b/ext/dom/document.c @@ -1441,19 +1441,65 @@ PHP_FUNCTION(dom_document_savexml) } /* }}} end dom_document_savexml */ +static xmlNodePtr php_dom_free_xinclude_node(xmlNodePtr cur TSRMLS_DC) { + xmlNodePtr xincnode; + + xincnode = cur; + cur = cur->next; + xmlUnlinkNode(xincnode); + php_libxml_node_free_resource(xincnode TSRMLS_CC); + + return cur; +} + +static void php_dom_remove_xinclude_nodes(xmlNodePtr cur TSRMLS_DC) { + while(cur) { + if (cur->type == XML_XINCLUDE_START) { + cur = php_dom_free_xinclude_node(cur TSRMLS_CC); + + /* XML_XINCLUDE_END node will be a sibling of XML_XINCLUDE_START */ + while(cur && cur->type != XML_XINCLUDE_END) { + cur = cur->next; + } + + if (cur && cur->type == XML_XINCLUDE_END) { + cur = php_dom_free_xinclude_node(cur TSRMLS_CC); + } + } else { + if (cur->type == XML_ELEMENT_NODE) { + php_dom_remove_xinclude_nodes(cur->children TSRMLS_CC); + } + cur = cur->next; + } + } +} + /* {{{ proto int dom_document_xinclude() Substitutues xincludes in a DomDocument */ PHP_FUNCTION(dom_document_xinclude) { zval *id; xmlDoc *docp; + xmlNodePtr root; int err; dom_object *intern; DOM_GET_THIS_OBJ(docp, id, xmlDocPtr, intern); err = xmlXIncludeProcess (docp); - + + /* XML_XINCLUDE_START and XML_XINCLUDE_END nodes need to be removed as these + are added via xmlXIncludeProcess to mark beginning and ending of xincluded document + but are not wanted in resulting document - must be done even if err as it could fail after + having processed some xincludes */ + root = (xmlNodePtr) docp->children; + while(root && root->type != XML_ELEMENT_NODE && root->type != XML_XINCLUDE_START) { + root = root->next; + } + if (root) { + php_dom_remove_xinclude_nodes(root TSRMLS_CC); + } + if (err) { RETVAL_LONG(err); } else { |