rrichards Sun Oct 5 07:52:23 2003 EDT Modified files: /php-src/ext/dom php_dom.c node.c element.c document.c Log: implement isDefaultNameSpace and baseURI nodeName and tagName return qualified names fix removeAttributeNode - takes domAttr as parameter better uri and file handling for document load method fix possible segfault when document is freed set get_property_ptr_ptr handler to NULL
Index: php-src/ext/dom/php_dom.c diff -u php-src/ext/dom/php_dom.c:1.34 php-src/ext/dom/php_dom.c:1.35 --- php-src/ext/dom/php_dom.c:1.34 Sun Oct 5 04:08:46 2003 +++ php-src/ext/dom/php_dom.c Sun Oct 5 07:52:22 2003 @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_dom.c,v 1.34 2003/10/05 08:08:46 zeev Exp $ */ +/* $Id: php_dom.c,v 1.35 2003/10/05 11:52:22 rrichards Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -250,13 +250,13 @@ /* }}} end dom_object_get_data */ /* {{{ php_dom_clear_object */ -static void php_dom_clear_object(dom_object *object TSRMLS_DC) +static int php_dom_clear_object(dom_object *object TSRMLS_DC) { if (object->prop_handler) { object->prop_handler = NULL; } decrement_node_ptr(object TSRMLS_CC); - decrement_document_reference(object TSRMLS_CC); + return decrement_document_reference(object TSRMLS_CC); } /* }}} end php_dom_clear_object */ @@ -284,14 +284,16 @@ /* }}} end php_dom_set_object */ /* {{{ dom_unregister_node */ -void dom_unregister_node(xmlNodePtr nodep TSRMLS_DC) +static int dom_unregister_node(xmlNodePtr nodep TSRMLS_DC) { dom_object *wrapper; - + wrapper = dom_object_get_data(nodep); if (wrapper != NULL ) { - php_dom_clear_object(wrapper TSRMLS_CC); + return php_dom_clear_object(wrapper TSRMLS_CC); } + + return -1; } /* }}} end dom_unregister_node */ @@ -405,17 +407,6 @@ } /* }}} */ -static zval **dom_property_get_ptr(zval *object, zval *member TSRMLS_DC) -{ - zval **prop_ptr; - zval *property; - - property = dom_read_property(object, member, 0 TSRMLS_CC); - prop_ptr = &property; - - return prop_ptr; -} - zend_module_entry dom_module_entry = { STANDARD_MODULE_HEADER, "dom", @@ -441,6 +432,7 @@ memcpy(&dom_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); dom_object_handlers.read_property = dom_read_property; dom_object_handlers.write_property = dom_write_property; + dom_object_handlers.get_property_ptr_ptr = NULL; zend_hash_init(&classes, 0, NULL, NULL, 1); @@ -871,7 +863,9 @@ curnode = node->next; xmlUnlinkNode(node); - dom_unregister_node(node TSRMLS_CC); + if (dom_unregister_node(node TSRMLS_CC) == 0) { + node->doc = NULL; + } dom_node_free(node); } } @@ -903,7 +897,9 @@ default: node_free_list((xmlNodePtr) node->properties TSRMLS_CC); } - dom_unregister_node(node TSRMLS_CC); + if (dom_unregister_node(node TSRMLS_CC) == 0) { + node->doc = NULL; + } dom_node_free(node); } else { dom_unregister_node(node TSRMLS_CC); Index: php-src/ext/dom/node.c diff -u php-src/ext/dom/node.c:1.11 php-src/ext/dom/node.c:1.12 --- php-src/ext/dom/node.c:1.11 Sun Aug 24 06:23:43 2003 +++ php-src/ext/dom/node.c Sun Oct 5 07:52:22 2003 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: node.c,v 1.11 2003/08/24 10:23:43 rrichards Exp $ */ +/* $Id: node.c,v 1.12 2003/10/05 11:52:22 rrichards Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -65,13 +65,23 @@ int dom_node_node_name_read(dom_object *obj, zval **retval TSRMLS_DC) { xmlNode *nodep; + xmlNsPtr ns; char *str = NULL; + xmlChar *qname = NULL; nodep = dom_object_get_node(obj); switch (nodep->type) { case XML_ATTRIBUTE_NODE: case XML_ELEMENT_NODE: + ns = nodep->ns; + if (ns != NULL && ns->prefix) { + qname = xmlStrdup(ns->prefix); + qname = xmlStrcat(qname, ":"); + } + qname = xmlStrcat(qname, nodep->name); + str = qname; + break; case XML_DOCUMENT_TYPE_NODE: case XML_DTD_NODE: case XML_PI_NODE: @@ -113,6 +123,10 @@ } else { ZVAL_EMPTY_STRING(*retval); } + + if (qname != NULL) { + xmlFree(qname); + } return SUCCESS; @@ -654,9 +668,21 @@ */ int dom_node_base_uri_read(dom_object *obj, zval **retval TSRMLS_DC) { - /* TODO: Implement this feature */ + xmlNode *nodep; + xmlChar *baseuri; + + nodep = dom_object_get_node(obj); + ALLOC_ZVAL(*retval); - ZVAL_NULL(*retval); + + baseuri = xmlNodeGetBase(nodep->doc, nodep); + if (baseuri) { + ZVAL_STRING(*retval, (char *) (baseuri), 1); + xmlFree(baseuri); + } else { + ZVAL_NULL(*retval); + } + return SUCCESS; } @@ -1315,18 +1341,38 @@ /* {{{ proto boolean dom_node_is_default_namespace(string namespaceURI); -URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-isDefaultNamespace +URL: http://www.w3.org/TR/DOM-Level-3-Core/core.html#Node3-isDefaultNamespace Since: DOM Level 3 */ PHP_FUNCTION(dom_node_is_default_namespace) { - DOM_NOT_IMPLEMENTED(); + zval *id; + xmlNodePtr nodep; + dom_object *intern; + xmlNsPtr nsptr; + int uri_len = 0; + char *uri; + + DOM_GET_THIS_OBJ(nodep, id, xmlNodePtr, intern); + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &uri, &uri_len) == FAILURE) { + return; + } + + if (uri_len > 0) { + nsptr = xmlSearchNs(nodep->doc, nodep, NULL); + if (nsptr && xmlStrEqual(nsptr->href, uri)) { + RETURN_TRUE; + } + } + + RETURN_FALSE; } /* }}} end dom_node_is_default_namespace */ /* {{{ proto domstring dom_node_lookup_namespace_uri(string prefix); -URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-lookupNamespaceURI +URL: http://www.w3.org/TR/DOM-Level-3-Core/core.html#Node3-lookupNamespaceURI Since: DOM Level 3 */ PHP_FUNCTION(dom_node_lookup_namespace_uri) Index: php-src/ext/dom/element.c diff -u php-src/ext/dom/element.c:1.13 php-src/ext/dom/element.c:1.14 --- php-src/ext/dom/element.c:1.13 Sun Aug 24 06:23:43 2003 +++ php-src/ext/dom/element.c Sun Oct 5 07:52:22 2003 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: element.c,v 1.13 2003/08/24 10:23:43 rrichards Exp $ */ +/* $Id: element.c,v 1.14 2003/10/05 11:52:22 rrichards Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -107,10 +107,20 @@ int dom_element_tag_name_read(dom_object *obj, zval **retval TSRMLS_DC) { xmlNodePtr nodep; + xmlNsPtr ns; + xmlChar *qname; nodep = dom_object_get_node(obj); ALLOC_ZVAL(*retval); - ZVAL_STRING(*retval, (char *) (nodep->name), 1); + ns = nodep->ns; + if (ns != NULL && ns->prefix) { + qname = xmlStrdup(ns->prefix); + qname = xmlStrcat(qname, ":"); + } + qname = xmlStrcat(qname, nodep->name); + ZVAL_STRING(*retval, qname, 1); + xmlFree(qname); + return SUCCESS; } @@ -309,14 +319,12 @@ existattrp = xmlHasProp(nodep, attrp->name); if (existattrp != NULL) { - if ((oldobj = dom_object_get_data((xmlNodePtr) existattrp)) == NULL) { - xmlUnlinkNode((xmlNodePtr) existattrp); - } else { - if (((node_ptr *)oldobj->ptr)->node == (xmlNodePtr) attrp) { - RETURN_NULL(); - } - xmlUnlinkNode((xmlNodePtr) existattrp); + if ((oldobj = dom_object_get_data((xmlNodePtr) existattrp)) != NULL && + ((node_ptr *)oldobj->ptr)->node == (xmlNodePtr) attrp) + { + RETURN_NULL(); } + xmlUnlinkNode((xmlNodePtr) existattrp); } if (attrp->doc == NULL && nodep->doc != NULL) { @@ -343,16 +351,15 @@ */ PHP_FUNCTION(dom_element_remove_attribute_node) { - zval *id; + zval *id, *node, *rv = NULL; xmlNode *nodep; xmlAttr *attrp; - dom_object *intern; - int name_len; - char *name; + dom_object *intern, *attrobj; + int ret; DOM_GET_THIS_OBJ(nodep, id, xmlNodePtr, intern); - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &node) == FAILURE) { return; } @@ -361,22 +368,16 @@ RETURN_FALSE; } - attrp = xmlHasProp(nodep,name); - if (attrp == NULL) { + DOM_GET_OBJ(attrp, node, xmlAttrPtr, attrobj); + + if (attrp->type != XML_ATTRIBUTE_NODE || attrp->parent != nodep) { + php_dom_throw_error(NOT_FOUND_ERR, dom_get_strict_error(intern->document) TSRMLS_CC); RETURN_FALSE; } - /* Check for registered nodes within attributes tree when attribute is not referenced - Unlink dependant nodes and free attribute if not registered */ - if (dom_object_get_data((xmlNodePtr) attrp) == NULL) { - node_list_unlink(attrp->children TSRMLS_CC); - xmlUnlinkNode((xmlNodePtr) attrp); - xmlFreeProp(attrp); - } else { - xmlUnlinkNode((xmlNodePtr) attrp); - } + xmlUnlinkNode((xmlNodePtr) attrp); - RETURN_TRUE; + DOM_RET_OBJ(rv, (xmlNodePtr) attrp, &ret, intern); } /* }}} end dom_element_remove_attribute_node */ @@ -684,14 +685,12 @@ } if (existattrp != NULL) { - if ((oldobj = dom_object_get_data((xmlNodePtr) existattrp)) == NULL) { - xmlUnlinkNode((xmlNodePtr) existattrp); - } else { - if (((node_ptr *)oldobj->ptr)->node == (xmlNodePtr) attrp) { - RETURN_NULL(); - } - xmlUnlinkNode((xmlNodePtr) existattrp); + if ((oldobj = dom_object_get_data((xmlNodePtr) existattrp)) != NULL && + ((node_ptr *)oldobj->ptr)->node == (xmlNodePtr) attrp) + { + RETURN_NULL(); } + xmlUnlinkNode((xmlNodePtr) existattrp); } if (attrp->doc == NULL && nodep->doc != NULL) { Index: php-src/ext/dom/document.c diff -u php-src/ext/dom/document.c:1.27 php-src/ext/dom/document.c:1.28 --- php-src/ext/dom/document.c:1.27 Wed Sep 24 08:56:37 2003 +++ php-src/ext/dom/document.c Sun Oct 5 07:52:22 2003 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: document.c,v 1.27 2003/09/24 12:56:37 rrichards Exp $ */ +/* $Id: document.c,v 1.28 2003/10/05 11:52:22 rrichards Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -1204,10 +1204,10 @@ } /* }}} end dom_document_document */ -/* {{{ static xmlDocPtr dom_document_parser(zval *id, int mode, char *source TSRMLS_DC) */ +/* {{{ */ static xmlDocPtr dom_document_parser(zval *id, int mode, char *source TSRMLS_DC) { xmlDocPtr ret; - xmlParserCtxtPtr ctxt; + xmlParserCtxtPtr ctxt = NULL; dom_doc_props *doc_props; dom_object *intern; dom_ref_obj *document = NULL; @@ -1232,13 +1232,61 @@ xmlInitParser(); + keep_blanks = xmlKeepBlanksDefault(keep_blanks); + if (mode == DOM_LOAD_FILE) { - expand_filepath(source, resolved_path TSRMLS_CC); - ctxt = xmlCreateFileParserCtxt(resolved_path); + + xmlURI *uri; + xmlChar *escsource; + char *file_dest; + int isFileUri = 0; + + uri = xmlCreateURI(); + escsource = xmlURIEscapeStr(source, ":"); + xmlParseURIReference(uri, escsource); + xmlFree(escsource); + + if (uri->scheme != NULL) { + /* absolute file uris - libxml only supports localhost or empty host */ + if (strncasecmp(source, "file:///",8) == 0) { + isFileUri = 1; +#ifdef PHP_WIN32 + source += 8; +#else + source += 7; +#endif + } else if (strncasecmp(source, "file://localhost/",17) == 0) { + isFileUri = 1; +#ifdef PHP_WIN32 + source += 17; +#else + source += 16; +#endif + } + } + + file_dest = source; + + if ((uri->scheme == NULL || isFileUri)) { + if (! VCWD_REALPATH(source, resolved_path)) { + expand_filepath(source, resolved_path TSRMLS_CC); + } + file_dest = resolved_path; + } + + xmlFreeURI(uri); + + if ((PG(safe_mode) && (!php_checkuid(file_dest, NULL, CHECKUID_CHECK_FILE_AND_DIR))) || php_check_open_basedir(file_dest TSRMLS_CC)) { + ctxt = NULL; + } else { + ctxt = xmlCreateFileParserCtxt(file_dest); + } } else { ctxt = xmlCreateDocParserCtxt(source); } + xmlKeepBlanksDefault(keep_blanks); + if (ctxt == NULL) { return(NULL); } @@ -1266,7 +1314,6 @@ ctxt->recovery = 0; ctxt->validate = validate; ctxt->loadsubset = (resolve_externals * XML_COMPLETE_ATTRS); - ctxt->keepBlanks = keep_blanks; ctxt->replaceEntities = substitute_ent; ctxt->vctxt.error = php_dom_ctx_error; @@ -1274,9 +1321,6 @@ if (ctxt->sax != NULL) { ctxt->sax->error = php_dom_ctx_error; - if (ctxt->keepBlanks == 0) { - ctxt->sax->ignorableWhitespace = ignorableWhitespace; - } } xmlParseDocument(ctxt); @@ -1297,7 +1341,7 @@ return(ret); } -/* }}} end dom_parser_document */ +/* }}} */ /* {{{ static void dom_parse_document(INTERNAL_FUNCTION_PARAMETERS, int mode) */ static void dom_parse_document(INTERNAL_FUNCTION_PARAMETERS, int mode) { @@ -1312,12 +1356,6 @@ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &source, &source_len) == FAILURE) { return; - } - - if (mode == DOM_LOAD_FILE) { - if ((PG(safe_mode) && (!php_checkuid(source, NULL, CHECKUID_CHECK_FILE_AND_DIR))) || php_check_open_basedir(source TSRMLS_CC)) { - RETURN_FALSE; - } } newdoc = dom_document_parser(id, mode, source TSRMLS_CC);
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php