summaryrefslogtreecommitdiff
path: root/ext/dom/document.c
diff options
context:
space:
mode:
authorRob Richards <rrichards@php.net>2004-01-07 15:33:25 +0000
committerRob Richards <rrichards@php.net>2004-01-07 15:33:25 +0000
commit6e65e1d82106b9aca0a2dcf498df54ffccae7168 (patch)
tree8f1006fba643d54dba653cdc06695e34a81bbb0d /ext/dom/document.c
parentee8f019b68b052eca8f32bf8573490f458f61160 (diff)
downloadphp-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.c48
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 {