rrichards Sat Jul 12 13:29:21 2003 EDT Modified files: /php-src/ext/dom php_dom.h php_dom.c node.c element.c documenttype.c Log: implement read only exceptions implement notation nodes changes for spec conformance
Index: php-src/ext/dom/php_dom.h diff -u php-src/ext/dom/php_dom.h:1.10 php-src/ext/dom/php_dom.h:1.11 --- php-src/ext/dom/php_dom.h:1.10 Thu Jul 10 07:17:25 2003 +++ php-src/ext/dom/php_dom.h Sat Jul 12 13:29:20 2003 @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_dom.h,v 1.10 2003/07/10 11:17:25 rrichards Exp $ */ +/* $Id: php_dom.h,v 1.11 2003/07/12 17:29:20 rrichards Exp $ */ #ifndef PHP_DOM_H #define PHP_DOM_H @@ -83,6 +83,8 @@ int dom_hierarchy(xmlNodePtr parent, xmlNodePtr child); int dom_has_feature(char *feature, char *version); void add_domdocument_properties(zval *id TSRMLS_DC); +int dom_node_is_read_only(xmlNodePtr node); +int dom_node_children_valid(xmlNodePtr node); #define REGISTER_DOM_CLASS(ce, name, parent_ce, funcs, entry) \ INIT_CLASS_ENTRY(ce, name, funcs); \ Index: php-src/ext/dom/php_dom.c diff -u php-src/ext/dom/php_dom.c:1.17 php-src/ext/dom/php_dom.c:1.18 --- php-src/ext/dom/php_dom.c:1.17 Thu Jul 10 07:17:25 2003 +++ php-src/ext/dom/php_dom.c Sat Jul 12 13:29:20 2003 @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_dom.c,v 1.17 2003/07/10 11:17:25 rrichards Exp $ */ +/* $Id: php_dom.c,v 1.18 2003/07/12 17:29:20 rrichards Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -73,6 +73,42 @@ {NULL, NULL, NULL} }; +/* {{{ int dom_node_is_read_only(xmlNodePtr node) */ +int dom_node_is_read_only(xmlNodePtr node) { + switch (node->type) { + case XML_ENTITY_REF_NODE: + case XML_ENTITY_NODE: + case XML_DOCUMENT_TYPE_NODE: + case XML_NOTATION_NODE: + case XML_DTD_NODE: + case XML_ELEMENT_DECL: + case XML_ATTRIBUTE_DECL: + case XML_ENTITY_DECL: + case XML_NAMESPACE_DECL: + return SUCCESS; + break; + default: + return FAILURE; + } +} +/* }}} end dom_node_is_read_only */ + +/* {{{ int dom_node_children_valid(xmlNodePtr node) */ +int dom_node_children_valid(xmlNodePtr node) { + switch (node->type) { + case XML_DOCUMENT_TYPE_NODE: + case XML_DTD_NODE: + case XML_PI_NODE: + case XML_COMMENT_NODE: + case XML_TEXT_NODE: + case XML_CDATA_SECTION_NODE: + return FAILURE; + break; + default: + return SUCCESS; + } +} +/* }}} end dom_node_children_valid */ /* {{{ int increment_document_reference(dom_object *object) */ int increment_document_reference(dom_object *object, xmlDocPtr docp TSRMLS_DC) { @@ -500,12 +536,15 @@ zend_hash_merge(&dom_documenttype_prop_handlers, &dom_node_prop_handlers, NULL, NULL, sizeof(dom_prop_handler), 0); zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_documenttype_prop_handlers, sizeof(dom_documenttype_prop_handlers), NULL); - REGISTER_DOM_CLASS(ce, "domnotation", dom_node_class_entry, php_dom_notation_class_functions, dom_notation_class_entry); + REGISTER_DOM_CLASS(ce, "domnotation", NULL, php_dom_notation_class_functions, dom_notation_class_entry); zend_hash_init(&dom_notation_prop_handlers, 0, NULL, NULL, 1); dom_register_prop_handler(&dom_notation_prop_handlers, "publicId", dom_notation_public_id_read, NULL TSRMLS_CC); dom_register_prop_handler(&dom_notation_prop_handlers, "systemId", dom_notation_system_id_read, NULL TSRMLS_CC); - zend_hash_merge(&dom_notation_prop_handlers, &dom_node_prop_handlers, NULL, NULL, sizeof(dom_prop_handler), 0); + /* Notation nodes are special */ + dom_register_prop_handler(&dom_notation_prop_handlers, "nodeName", dom_node_node_name_read, NULL TSRMLS_CC); + dom_register_prop_handler(&dom_notation_prop_handlers, "nodeValue", dom_node_node_value_read, dom_node_node_value_write TSRMLS_CC); + dom_register_prop_handler(&dom_notation_prop_handlers, "attributes", dom_node_attributes_read, NULL TSRMLS_CC); zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_notation_prop_handlers, sizeof(dom_notation_prop_handlers), NULL); REGISTER_DOM_CLASS(ce, "domentity", dom_node_class_entry, php_dom_entity_class_functions, dom_entity_class_entry); @@ -620,7 +659,7 @@ uncomment the following line, this will tell you the amount of not freed memory and the total used memory into apaches error_log */ /* xmlMemoryDump();*/ - +xmlMemoryDump(); return SUCCESS; } @@ -669,6 +708,23 @@ xmlFreeProp((xmlAttrPtr) node); break; case XML_ENTITY_DECL: + case XML_ELEMENT_DECL: + case XML_ATTRIBUTE_DECL: + case XML_NAMESPACE_DECL: + /* These can never stand alone */ + break; + case XML_NOTATION_NODE: + /* These require special handling */ + if (node->name != NULL) { + xmlFree((char *) node->name); + } + if (((xmlEntityPtr) node)->ExternalID != NULL) { + xmlFree((char *) ((xmlEntityPtr) node)->ExternalID); + } + if (((xmlEntityPtr) node)->SystemID != NULL) { + xmlFree((char *) ((xmlEntityPtr) node)->SystemID); + } + xmlFree(node); break; default: xmlFreeNode(node); @@ -688,6 +744,8 @@ node = curnode; switch (node->type) { /* Skip property freeing for the following types */ + case XML_NOTATION_NODE: + break; case XML_ENTITY_REF_NODE: node_free_list((xmlNodePtr) node->properties TSRMLS_CC); break; Index: php-src/ext/dom/node.c diff -u php-src/ext/dom/node.c:1.7 php-src/ext/dom/node.c:1.8 --- php-src/ext/dom/node.c:1.7 Mon Jul 7 15:37:32 2003 +++ php-src/ext/dom/node.c Sat Jul 12 13:29:20 2003 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: node.c,v 1.7 2003/07/07 19:37:32 rrichards Exp $ */ +/* $Id: node.c,v 1.8 2003/07/12 17:29:20 rrichards Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -154,7 +154,7 @@ ZVAL_STRING(*retval, str, 1); xmlFree(str); } else { - ZVAL_EMPTY_STRING(*retval); + ZVAL_NULL(*retval); } @@ -202,7 +202,14 @@ nodep = dom_object_get_node(obj); ALLOC_ZVAL(*retval); - ZVAL_LONG(*retval, nodep->type); + + /* Specs dictate that they are both type XML_DOCUMENT_TYPE_NODE */ + if (nodep->type == XML_DTD_NODE) { + ZVAL_LONG(*retval, XML_DOCUMENT_TYPE_NODE); + } else { + ZVAL_LONG(*retval, nodep->type); + } + return SUCCESS; } @@ -252,23 +259,27 @@ nodep = dom_object_get_node(obj); - if ((nodep->type == XML_DOCUMENT_NODE) || (nodep->type == XML_HTML_DOCUMENT_NODE)) { - last = ((xmlDoc *) nodep)->children; + if (dom_node_children_valid(nodep) == SUCCESS) { + if ((nodep->type == XML_DOCUMENT_NODE) || (nodep->type == XML_HTML_DOCUMENT_NODE)) { + last = ((xmlDoc *) nodep)->children; + } else { + last = nodep->children; + } } else { - last = nodep->children; + last = NULL; } + MAKE_STD_ZVAL(*retval); array_init(*retval); - if (last) { - while (last) { - zval *child; - MAKE_STD_ZVAL(child); - child = php_dom_create_object(last, &ret, NULL, child, obj TSRMLS_CC); - add_next_index_zval(*retval, child); - last = last->next; - } + while (last) { + zval *child; + MAKE_STD_ZVAL(child); + child = php_dom_create_object(last, &ret, NULL, child, obj TSRMLS_CC); + add_next_index_zval(*retval, child); + last = last->next; } + return SUCCESS; } @@ -283,12 +294,15 @@ */ int dom_node_first_child_read(dom_object *obj, zval **retval TSRMLS_DC) { - xmlNode *nodep, *first; + xmlNode *nodep, *first = NULL; int ret; nodep = dom_object_get_node(obj); - first = nodep->children; + if (dom_node_children_valid(nodep) == SUCCESS) { + first = nodep->children; + } + if (!first) { return FAILURE; } @@ -313,12 +327,15 @@ */ int dom_node_last_child_read(dom_object *obj, zval **retval TSRMLS_DC) { - xmlNode *nodep, *last; + xmlNode *nodep, *last = NULL; int ret; nodep = dom_object_get_node(obj); - last = nodep->last; + if (dom_node_children_valid(nodep) == SUCCESS) { + last = nodep->last; + } + if (!last) { return FAILURE; } @@ -499,7 +516,7 @@ if(str != NULL) { ZVAL_STRING(*retval, str, 1); } else { - ZVAL_EMPTY_STRING(*retval); + ZVAL_NULL(*retval); } return SUCCESS; @@ -709,6 +726,12 @@ new_child = NULL; + if (dom_node_is_read_only(parentp) == SUCCESS || + (child->parent != NULL && dom_node_is_read_only(child->parent) == SUCCESS)) { + php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, &return_value TSRMLS_CC); + RETURN_FALSE; + } + if (dom_hierarchy(parentp, child) == FAILURE) { php_dom_throw_error(HIERARCHY_REQUEST_ERR, &return_value TSRMLS_CC); php_error_docref(NULL TSRMLS_CC, E_WARNING, "Hierarchy Request Error"); @@ -854,6 +877,10 @@ DOM_GET_THIS_OBJ(nodep, id, xmlNodePtr, intern); + if (dom_node_children_valid(nodep) == FAILURE) { + RETURN_FALSE; + } + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "oo", &newnode, &oldnode) == FAILURE) { return; } @@ -866,6 +893,12 @@ RETURN_FALSE; } + if (dom_node_is_read_only(nodep) == SUCCESS || + (newchild->parent != NULL && dom_node_is_read_only(newchild->parent) == SUCCESS)) { + php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, &return_value TSRMLS_CC); + RETURN_FALSE; + } + if (newchild->doc != nodep->doc && newchild->doc != NULL) { php_dom_throw_error(WRONG_DOCUMENT_ERR, &return_value TSRMLS_CC); php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't add newnode as it was created from a different document"); @@ -892,6 +925,7 @@ if (oldchild != newchild) { xmlNodePtr node; if (newchild->doc == NULL && nodep->doc != NULL) { + xmlSetTreeDoc(newchild, nodep->doc); newchildobj->document = intern->document; increment_document_reference(newchildobj, NULL TSRMLS_CC); } @@ -925,8 +959,18 @@ return; } + if (dom_node_children_valid(nodep) == FAILURE) { + RETURN_FALSE; + } + DOM_GET_OBJ(child, node, xmlNodePtr, childobj); + if (dom_node_is_read_only(nodep) == SUCCESS || + (child->parent != NULL && dom_node_is_read_only(child->parent) == SUCCESS)) { + php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, &return_value TSRMLS_CC); + RETURN_FALSE; + } + children = nodep->children; if (!children) { php_dom_throw_error(NOT_FOUND_ERR, &return_value TSRMLS_CC); @@ -966,8 +1010,18 @@ return; } + if (dom_node_children_valid(nodep) == FAILURE) { + RETURN_FALSE; + } + DOM_GET_OBJ(child, node, xmlNodePtr, childobj); + if (dom_node_is_read_only(nodep) == SUCCESS || + (child->parent != NULL && dom_node_is_read_only(child->parent) == SUCCESS)) { + php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, &return_value TSRMLS_CC); + RETURN_FALSE; + } + if (dom_hierarchy(nodep, child) == FAILURE) { php_dom_throw_error(HIERARCHY_REQUEST_ERR, &return_value TSRMLS_CC); php_error_docref(NULL TSRMLS_CC, E_WARNING, "Hierarchy Request Error"); @@ -1053,6 +1107,10 @@ DOM_GET_THIS_OBJ(nodep, id, xmlNodePtr, intern); DOM_NO_ARGS(); + + if (dom_node_children_valid(nodep) == FAILURE) { + RETURN_FALSE; + } if (nodep->children) { RETURN_TRUE; Index: php-src/ext/dom/element.c diff -u php-src/ext/dom/element.c:1.7 php-src/ext/dom/element.c:1.8 --- php-src/ext/dom/element.c:1.7 Tue Jul 8 13:00:49 2003 +++ php-src/ext/dom/element.c Sat Jul 12 13:29:20 2003 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: element.c,v 1.7 2003/07/08 17:00:49 rrichards Exp $ */ +/* $Id: element.c,v 1.8 2003/07/12 17:29:20 rrichards Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -183,6 +183,11 @@ return; } + if (dom_node_is_read_only(nodep) == SUCCESS) { + php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, &return_value TSRMLS_CC); + RETURN_FALSE; + } + attr = xmlHasProp(nodep,name); if (attr != NULL) { node_list_unlink(attr->children TSRMLS_CC); @@ -218,6 +223,11 @@ return; } + if (dom_node_is_read_only(nodep) == SUCCESS) { + php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, &return_value TSRMLS_CC); + RETURN_FALSE; + } + attrp = xmlHasProp(nodep,name); if (attrp == NULL) { RETURN_FALSE; @@ -284,6 +294,11 @@ return; } + if (dom_node_is_read_only(nodep) == SUCCESS) { + php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, &return_value TSRMLS_CC); + RETURN_FALSE; + } + DOM_GET_OBJ(attrp, node, xmlAttrPtr, attrobj); if (attrp->type != XML_ATTRIBUTE_NODE) { @@ -340,6 +355,11 @@ return; } + if (dom_node_is_read_only(nodep) == SUCCESS) { + php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, &return_value TSRMLS_CC); + RETURN_FALSE; + } + attrp = xmlHasProp(nodep,name); if (attrp == NULL) { RETURN_FALSE; @@ -486,6 +506,12 @@ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &uri, &uri_len, &name, &name_len) == FAILURE) { return; } + + if (dom_node_is_read_only(elemp) == SUCCESS) { + php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, &return_value TSRMLS_CC); + RETURN_FALSE; + } + nsptr = xmlSearchNsByHref (elemp->doc, elemp, uri); if (nsptr == NULL) { nsptr = dom_get_ns(uri, name, uri_len, name_len, &errorcode, (char **) &localname); @@ -538,6 +564,11 @@ return; } + if (dom_node_is_read_only(nodep) == SUCCESS) { + php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, &return_value TSRMLS_CC); + RETURN_FALSE; + } + if (xmlStrEqual(uri, DOM_XMLNS_NAMESPACE)) { DOM_NOT_IMPLEMENTED(); } else { @@ -618,6 +649,11 @@ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &node) == FAILURE) { return; + } + + if (dom_node_is_read_only(nodep) == SUCCESS) { + php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, &return_value TSRMLS_CC); + RETURN_FALSE; } DOM_GET_OBJ(attrp, node, xmlAttrPtr, attrobj); Index: php-src/ext/dom/documenttype.c diff -u php-src/ext/dom/documenttype.c:1.4 php-src/ext/dom/documenttype.c:1.5 --- php-src/ext/dom/documenttype.c:1.4 Mon Jul 7 15:37:32 2003 +++ php-src/ext/dom/documenttype.c Sat Jul 12 13:29:20 2003 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: documenttype.c,v 1.4 2003/07/07 19:37:32 rrichards Exp $ */ +/* $Id: documenttype.c,v 1.5 2003/07/12 17:29:20 rrichards Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -33,6 +33,13 @@ xmlNode *node; }; +typedef struct _notationIterator notationIterator; +struct _notationIterator { + int cur; + int index; + xmlNotation *notation; +}; + static void itemHashScanner (void *payload, void *data, xmlChar *name) { nodeIterator *priv = (nodeIterator *)data; @@ -45,6 +52,31 @@ } } +/* {{{ static xmlEntityPtr create_notation(const xmlChar *name, + const xmlChar *ExternalID, const xmlChar *SystemID) */ +static xmlNodePtr create_notation(const xmlChar *name, + const xmlChar *ExternalID, const xmlChar *SystemID) { + xmlEntityPtr ret; + + ret = (xmlEntityPtr) xmlMalloc(sizeof(xmlEntity)); + memset(ret, 0, sizeof(xmlEntity)); + ret->type = XML_NOTATION_NODE; + ret->name = xmlStrdup(name); + ret->ExternalID = xmlStrdup(ExternalID); + ret->SystemID = xmlStrdup(SystemID); + ret->length = 0; + ret->content = NULL; + ret->URI = NULL; + ret->orig = NULL; + ret->children = NULL; + ret->parent = NULL; + ret->doc = NULL; + ret->_private = NULL; + ret->last = NULL; + ret->prev = NULL; + return((xmlNodePtr) ret); +} + /* * class domdocumenttype extends domnode * @@ -133,7 +165,8 @@ { xmlDtdPtr doctypep; xmlHashTable *notationht; - nodeIterator *iter; + notationIterator *iter; + xmlNotationPtr notep = NULL; xmlNode *nodep = NULL; int ret, htsize, index = 0; @@ -149,12 +182,13 @@ while (index < htsize) { iter->cur = 0; iter->index = index; - iter->node = NULL; + iter->notation = NULL; xmlHashScan(notationht, itemHashScanner, iter); index++; - nodep = iter->node; - if (nodep != NULL) { + notep = iter->notation; + if (notep != NULL) { zval *child; + nodep = create_notation(notep->name, notep->PublicID, notep->SystemID); MAKE_STD_ZVAL(child); child = php_dom_create_object(nodep, &ret, NULL, child, obj TSRMLS_CC); add_assoc_zval(*retval, (char *) nodep->name, child);
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php