rrichards Fri Oct 17 11:56:07 2003 EDT Modified files: (Branch: PHP_4_3) /php-src/ext/domxml php_domxml.c Log: Fix bug #25888 (Crash of php.exe when xpath_eval of a namespace) memleak fix in domxml_node_name keep blanks loading document fix Index: php-src/ext/domxml/php_domxml.c diff -u php-src/ext/domxml/php_domxml.c:1.218.2.32 php-src/ext/domxml/php_domxml.c:1.218.2.33 --- php-src/ext/domxml/php_domxml.c:1.218.2.32 Wed Sep 17 15:34:42 2003 +++ php-src/ext/domxml/php_domxml.c Fri Oct 17 11:56:06 2003 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_domxml.c,v 1.218.2.32 2003/09/17 19:34:42 rrichards Exp $ */ +/* $Id: php_domxml.c,v 1.218.2.33 2003/10/17 15:56:06 rrichards Exp $ */ /* TODO * - Support Notation Nodes @@ -160,6 +160,7 @@ static int le_domxmlcommentp; static int le_domxmlnotationp; static int le_domxmlparserp; +static int le_domxmlnamespacep; /*static int le_domxmlentityp;*/ static int le_domxmlentityrefp; @@ -513,6 +514,13 @@ }; static zend_function_entry php_domxmlns_class_functions[] = { + PHP_FALIAS(node_name, domxml_node_name, NULL) + PHP_FALIAS(node_type, domxml_node_type, NULL) + PHP_FALIAS(node_value, domxml_node_value, NULL) + PHP_FALIAS(prefix, domxml_node_prefix, NULL) + PHP_FALIAS(namespace_uri, domxml_node_namespace_uri, NULL) + PHP_FALIAS(owner_document, domxml_node_owner_document, NULL) + PHP_FALIAS(parent_node, domxml_node_parent, NULL) {NULL, NULL, NULL} }; @@ -733,11 +741,19 @@ /* if node has no parent, it will not be freed by php_free_xml_doc, so do it here and for all children as well. */ - if (node->parent == NULL) { + if (node->parent == NULL || node->type == XML_NAMESPACE_DECL) { /* Attribute Nodes ccontain accessible children attr_list_wrapper_dtor(node->properties); */ xmlSetTreeDoc(node, NULL); - node_list_wrapper_dtor((xmlNodePtr) node->properties, 1 TSRMLS_CC); + if (node->type == XML_NAMESPACE_DECL) { + if (node->ns) { + xmlFreeNs(node->ns); + node->ns = NULL; + } + node->type = XML_ELEMENT_NODE; + } else { + node_list_wrapper_dtor((xmlNodePtr) node->properties, 1 TSRMLS_CC); + } node_list_wrapper_dtor(node->children, 1 TSRMLS_CC); node_wrapper_dtor(node); xmlFreeNode(node); @@ -1371,6 +1387,22 @@ break; } + case XML_NAMESPACE_DECL: + { + xmlNodePtr nodep = obj; + if(!wrapper_in) + object_init_ex(wrapper, domxmlns_class_entry); + rsrc_type = le_domxmlnamespacep; + add_property_long(wrapper, "type", Z_TYPE_P(nodep)); + add_property_stringl(wrapper, "name", (char *) nodep->name, strlen(nodep->name), 1); + content = xmlNodeGetContent(nodep->children); + if (content) { + add_property_stringl(wrapper, "value", (char *) content, strlen(content), 1); + xmlFree(content); + } + break; + } + default: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unsupported node type: %d\n", Z_TYPE_P(obj)); FREE_ZVAL(wrapper); @@ -1508,6 +1540,7 @@ le_domxmlpip = zend_register_list_destructors_ex(php_free_xml_node, NULL, "dompi", module_number); le_domxmlparserp = zend_register_list_destructors_ex(php_free_xml_parser, NULL, "domparser", module_number); le_domxmldoctypep = zend_register_list_destructors_ex(php_free_xml_node, NULL, "domdocumenttype", module_number); + le_domxmlnamespacep = zend_register_list_destructors_ex(php_free_xml_node, NULL, "domnamespacenode", module_number); le_domxmldocp = zend_register_list_destructors_ex(php_free_xml_doc, NULL, "domdocument", module_number); /* Freeing the document contains freeing the complete tree. Therefore nodes, attributes etc. may not be freed seperately. @@ -1890,6 +1923,7 @@ zval *id; xmlNode *n; int fullQName = 0; + xmlChar *qname = NULL; const char *str = NULL; DOMXML_PARAM_ONE(n, id, le_domxmlnodep,"|b",&fullQName); @@ -1897,16 +1931,24 @@ switch (Z_TYPE_P(n)) { case XML_ELEMENT_NODE: if (fullQName && n->ns && n->ns->prefix) { - /* there is maybe a better way of doing this...*/ - char *tmpstr; - tmpstr = (char*) emalloc((strlen(n->ns->prefix)+strlen(n->name)) * sizeof(char)) ; - sprintf(tmpstr,"%s:%s", (char*) n->ns->prefix, (char*) n->name); - str = strdup(tmpstr); - efree(tmpstr); + qname = xmlStrdup(n->ns->prefix); + qname = xmlStrcat(qname, ":"); + qname = xmlStrcat(qname, n->name); + str = qname; } else { str = n->name; } break; + case XML_NAMESPACE_DECL: + if (n->ns != NULL && n->ns->prefix) { + qname = xmlStrdup("xmlns"); + qname = xmlStrcat(qname, ":"); + qname = xmlStrcat(qname, n->name); + str = qname; + } else { + str = (char *) n->name; + } + break; case XML_TEXT_NODE: str = "#text"; @@ -1950,7 +1992,10 @@ } if(str != NULL) { - RETURN_STRING((char *) str, 1); + RETVAL_STRING((char *) str, 1); + if (qname) { + xmlFree(qname); + } } else { RETURN_EMPTY_STRING(); } @@ -1976,6 +2021,11 @@ case XML_PI_NODE: str = n->content; break; + case XML_NAMESPACE_DECL: + if (n->children) { + str = n->children->content; + } + break; default: str = NULL; break; @@ -3935,12 +3985,20 @@ xmlInitParser(); + keep_blanks = xmlKeepBlanksDefault(keep_blanks); + if (loadtype == DOMXML_LOAD_FILE) { ctxt = xmlCreateFileParserCtxt(source); } else { ctxt = xmlCreateDocParserCtxt(source); } + xmlKeepBlanksDefault(keep_blanks); + /* xmlIndentTreeOutput default is changed in xmlKeepBlanksDefault + reset back to 1 which is default value */ + + xmlIndentTreeOutput = 1; + if (ctxt == NULL) { return(NULL); } @@ -3954,7 +4012,6 @@ ctxt->validate = validate; ctxt->loadsubset = resolve_externals; - ctxt->keepBlanks = keep_blanks; ctxt->replaceEntities = substitute_ent; if (data != NULL) { @@ -4885,6 +4942,8 @@ if (contextnode) { DOMXML_GET_OBJ(contextnodep, contextnode, le_domxmlnodep); + } else { + contextnodep = xmlDocGetRootElement(ctxp->doc); } ctxp->node = contextnodep; @@ -4941,9 +5000,27 @@ xmlNodePtr node = nodesetp->nodeTab[i]; zval *child; int retnode; + xmlNsPtr curns; + xmlNodePtr nsparent; + + if (node->type == XML_NAMESPACE_DECL) { + nsparent = node->_private; + curns = xmlNewNs(NULL, node->name, NULL); + if (node->children) { + curns->prefix = xmlStrdup((char *) node->children); + } + if (node->children) { + node = xmlNewDocNode(ctxp->doc, NULL, (char *) node->children, node->name); + } else { + node = xmlNewDocNode(ctxp->doc, NULL, "xmlns", node->name); + } + node->type = XML_NAMESPACE_DECL; + node->parent = nsparent; + node->ns = curns; + } - /* construct a node object */ child = php_domobject_new(node, &retnode, NULL TSRMLS_CC); + zend_hash_next_index_insert(Z_ARRVAL_P(arr), &child, sizeof(zval *), NULL); } zend_hash_update(Z_OBJPROP_P(rv), "nodeset", sizeof("nodeset"), (void *) &arr, sizeof(zval *), NULL);
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php