Index: ext/domxml/php_domxml.c =================================================================== RCS file: /repository/php4/ext/domxml/php_domxml.c,v retrieving revision 1.133 diff -u -r1.133 php_domxml.c --- ext/domxml/php_domxml.c 4 Apr 2002 12:16:48 -0000 1.133 +++ ext/domxml/php_domxml.c 13 Apr 2002 11:05:17 -0000 @@ -1873,19 +1925,60 @@ RETURN_FALSE; } +#if 0 if (NULL == (new_child = xmlCopyNode(child, 1))) { php_error(E_WARNING, "%s(): unable to clone node", get_active_function_name(TSRMLS_C)); RETURN_FALSE; } +#endif + + /* Note this comment from libxml2::tree.c in xmlAddChild(): + * + * // If cur is a TEXT node, merge its content with adjacent TEXT nodes + * // cur is then freed. + * + * (cur is our "child" variable.) + * Because of this behaviour in libxml2 we have to unlink a TEXT node from + * our le_domxmlnodep before performing xmlAddChild() + * We get wrapper and handle in every case, b/c the TEXT node's to not have to be + * coalesced, which makes the handling a bit hackish: + * - remove a text node, always, b/c we cannot use the possible free'd memory + * - readd the node in case it has not been coalesced + * + * the current php CVS (as of 2002-02-10) uses xmlCopyNode() as a solution. + * this is bad, because your PHP code won't be able to freely + * store copies of a nodeID. b/c it will be rendered invalid after each use of + * ->add_child() + */ + if (child->type == XML_TEXT_NODE) { + zval **handle, *wrapper; + + wrapper = dom_object_get_data(child); + if (wrapper) { + if (zend_hash_index_find(Z_OBJPROP_P(wrapper), 0, (void **)&handle) == FAILURE) { + php_error(E_WARNING, "%s() underlying object missing", get_active_function_name(TSRMLS_C)); + } + else + zend_list_delete(Z_LVAL_PP(handle)); + } + } - child = xmlAddChild(nodep, new_child); + new_child = xmlAddChild(nodep, child); if (NULL == child) { php_error(E_WARNING, "%s(): couldn't add child", get_active_function_name(TSRMLS_C)); RETURN_FALSE; } - DOMXML_RET_OBJ(rv, child, &ret); + /* check, if we have to readd the TEXT node to le_domxmlnodep + * because it has not been coalesced and free()d. + */ + if (new_child == child && child->type == XML_TEXT_NODE) { + zval *wrapper; + wrapper = php_domobject_new(child, &ret TSRMLS_CC); + } + + DOMXML_RET_OBJ(rv, new_child, &ret); } /* }}} */