mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
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
This commit is contained in:
parent
4de32429f5
commit
c21e78ddf2
4 changed files with 149 additions and 70 deletions
|
@ -1204,10 +1204,10 @@ PHP_FUNCTION(dom_document_document)
|
|||
}
|
||||
/* }}} 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 @@ static xmlDocPtr dom_document_parser(zval *id, int mode, char *source TSRMLS_DC)
|
|||
|
||||
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 @@ static xmlDocPtr dom_document_parser(zval *id, int mode, char *source TSRMLS_DC)
|
|||
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 @@ static xmlDocPtr dom_document_parser(zval *id, int mode, char *source TSRMLS_DC)
|
|||
|
||||
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 @@ static xmlDocPtr dom_document_parser(zval *id, int mode, char *source TSRMLS_DC)
|
|||
|
||||
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) {
|
||||
|
@ -1314,12 +1358,6 @@ static void dom_parse_document(INTERNAL_FUNCTION_PARAMETERS, int mode) {
|
|||
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);
|
||||
|
||||
if (!newdoc)
|
||||
|
|
|
@ -107,10 +107,20 @@ Since:
|
|||
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 @@ PHP_FUNCTION(dom_element_set_attribute_node)
|
|||
|
||||
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 @@ Since:
|
|||
*/
|
||||
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 @@ PHP_FUNCTION(dom_element_remove_attribute_node)
|
|||
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 @@ PHP_FUNCTION(dom_element_set_attribute_node_ns)
|
|||
}
|
||||
|
||||
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) {
|
||||
|
|
|
@ -65,13 +65,23 @@ Since:
|
|||
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 @@ int dom_node_node_name_read(dom_object *obj, zval **retval TSRMLS_DC)
|
|||
} else {
|
||||
ZVAL_EMPTY_STRING(*retval);
|
||||
}
|
||||
|
||||
if (qname != NULL) {
|
||||
xmlFree(qname);
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
|
||||
|
@ -654,9 +668,21 @@ Since: DOM Level 3
|
|||
*/
|
||||
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 @@ PHP_FUNCTION(dom_node_lookup_prefix)
|
|||
|
||||
|
||||
/* {{{ 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)
|
||||
|
|
|
@ -250,13 +250,13 @@ dom_object *dom_object_get_data(xmlNodePtr obj)
|
|||
/* }}} 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 @@ void php_dom_set_object(dom_object *object, xmlNodePtr obj TSRMLS_DC)
|
|||
/* }}} 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 @@ void dom_write_property(zval *object, zval *member, zval *value TSRMLS_DC)
|
|||
}
|
||||
/* }}} */
|
||||
|
||||
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 @@ PHP_MINIT_FUNCTION(dom)
|
|||
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 @@ void node_free_list(xmlNodePtr node TSRMLS_DC)
|
|||
|
||||
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 @@ void node_free_resource(xmlNodePtr node TSRMLS_DC)
|
|||
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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue