summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
authorRob Richards <rrichards@php.net>2003-06-07 13:30:58 +0000
committerRob Richards <rrichards@php.net>2003-06-07 13:30:58 +0000
commit0565d9724bb3ea229b004e5a21b0d7ab8a62a553 (patch)
treec1c34ba23ec04eca75157e4e2734499f60fb4c58 /ext
parenteccfbe5f88651a50e2c6994f6f357d3e176e2ced (diff)
downloadphp-git-0565d9724bb3ea229b004e5a21b0d7ab8a62a553.tar.gz
fix more memory overruns
initial definition for document ref counting fixed property access to support all objects clear property handler from invalid objects until ref count implemented
Diffstat (limited to 'ext')
-rw-r--r--ext/dom/php_dom.c79
-rw-r--r--ext/dom/xml_common.h7
2 files changed, 56 insertions, 30 deletions
diff --git a/ext/dom/php_dom.c b/ext/dom/php_dom.c
index 5fa498b2e1..fbb3b8111a 100644
--- a/ext/dom/php_dom.c
+++ b/ext/dom/php_dom.c
@@ -97,6 +97,9 @@ static void php_dom_clear_object(zval *wrapper TSRMLS_DC)
object = (dom_object *)zend_objects_get_address(wrapper TSRMLS_CC);
object->ptr = NULL;
+ if (object->prop_handler) {
+ object->prop_handler = NULL;
+ }
}
/* }}} */
@@ -235,27 +238,24 @@ zval *dom_read_property(zval *object, zval *member TSRMLS_DC)
ret = FAILURE;
obj = (dom_object *)zend_objects_get_address(object TSRMLS_CC);
- if (obj->ptr != NULL) {
- if (obj->prop_handler != NULL) {
- ret = zend_hash_find(obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void **) &hnd);
- }
+
+ if (obj->prop_handler != NULL) {
+ ret = zend_hash_find(obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void **) &hnd);
+ }
+ if (ret == SUCCESS) {
+ ret = hnd->read_func(obj, &retval TSRMLS_CC);
if (ret == SUCCESS) {
- ret = hnd->read_func(obj, &retval TSRMLS_CC);
- if (ret == SUCCESS) {
- /* ensure we're creating a temporary variable */
- retval->refcount = 1;
- PZVAL_UNLOCK(retval);
- } else {
- retval = EG(uninitialized_zval_ptr);
- }
+ /* ensure we're creating a temporary variable */
+ retval->refcount = 1;
+ PZVAL_UNLOCK(retval);
} else {
- std_hnd = zend_get_std_object_handlers();
- retval = std_hnd->read_property(object, member TSRMLS_CC);
+ retval = EG(uninitialized_zval_ptr);
}
} else {
- retval = EG(uninitialized_zval_ptr);
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Underlying object missing");
+ std_hnd = zend_get_std_object_handlers();
+ retval = std_hnd->read_property(object, member TSRMLS_CC);
}
+
if (member == &tmp_member) {
zval_dtor(member);
}
@@ -281,19 +281,17 @@ void dom_write_property(zval *object, zval *member, zval *value TSRMLS_DC)
ret = FAILURE;
obj = (dom_object *)zend_objects_get_address(object TSRMLS_CC);
- if (obj->ptr != NULL) {
- if (obj->prop_handler != NULL) {
- ret = zend_hash_find((HashTable *)obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void **) &hnd);
- }
- if (ret == SUCCESS) {
- hnd->write_func(obj, value TSRMLS_CC);
- } else {
- std_hnd = zend_get_std_object_handlers();
- std_hnd->write_property(object, member, value TSRMLS_CC);
- }
+
+ if (obj->prop_handler != NULL) {
+ ret = zend_hash_find((HashTable *)obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void **) &hnd);
+ }
+ if (ret == SUCCESS) {
+ hnd->write_func(obj, value TSRMLS_CC);
} else {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Underlying object missing");
+ std_hnd = zend_get_std_object_handlers();
+ std_hnd->write_property(object, member, value TSRMLS_CC);
}
+
if (member == &tmp_member) {
zval_dtor(member);
}
@@ -670,6 +668,24 @@ void node_list_unlink(xmlNodePtr node TSRMLS_DC)
}
/* }}} end node_list_unlink */
+
+/* {{{ void dom_node_free(xmlNodePtr node) */
+void dom_node_free(xmlNodePtr node)
+{
+ if(node) {
+ switch (node->type) {
+ case XML_ATTRIBUTE_NODE:
+ xmlFreeProp((xmlAttrPtr) node);
+ break;
+ case XML_ENTITY_DECL:
+ break;
+ default:
+ xmlFreeNode(node);
+ }
+ }
+}
+/* }}} end dom_node_free */
+
/* {{{ node_free_list */
void node_free_list(xmlNodePtr node TSRMLS_DC)
{
@@ -679,23 +695,27 @@ void node_free_list(xmlNodePtr node TSRMLS_DC)
curnode = node;
while (curnode != NULL) {
node = curnode;
- node_free_list(node->children TSRMLS_CC);
switch (node->type) {
/* Skip property freeing for the following types */
+ case XML_ENTITY_REF_NODE:
+ node_free_list((xmlNodePtr) node->properties TSRMLS_CC);
+ break;
case XML_ATTRIBUTE_DECL:
case XML_DTD_NODE:
case XML_DOCUMENT_TYPE_NODE:
case XML_ENTITY_DECL:
case XML_ATTRIBUTE_NODE:
+ node_free_list(node->children TSRMLS_CC);
break;
default:
+ node_free_list(node->children TSRMLS_CC);
node_free_list((xmlNodePtr) node->properties TSRMLS_CC);
}
dom_unregister_node(node TSRMLS_CC);
curnode = node->next;
xmlUnlinkNode(node);
- xmlFreeNode(node);
+ dom_node_free(node);
}
}
}
@@ -810,6 +830,7 @@ zend_object_value dom_objects_new(zend_class_entry *class_type TSRMLS_DC)
intern->ptr = NULL;
intern->node_list = NULL;
intern->prop_handler = NULL;
+ intern->document = NULL;
base_class = class_type;
while(base_class->type != ZEND_INTERNAL_CLASS && base_class->parent != NULL) {
diff --git a/ext/dom/xml_common.h b/ext/dom/xml_common.h
index 6188e56020..0c88bae040 100644
--- a/ext/dom/xml_common.h
+++ b/ext/dom/xml_common.h
@@ -27,9 +27,15 @@ typedef struct _node_list_pointer {
void *next;
} node_list_pointer;
+typedef struct _dom_ref_obj {
+ void *ptr;
+ int refcount;
+} dom_ref_obj;
+
typedef struct _dom_object {
zend_object std;
void *ptr;
+ dom_ref_obj *document;
HashTable *prop_handler;
node_list_pointer *node_list;
} dom_object;
@@ -71,7 +77,6 @@ zend_object_handlers dom_object_handlers;
INIT_CLASS_ENTRY(ce, name, funcs); \
ce.create_object = dom_objects_new; \
entry = zend_register_internal_class_ex(&ce, parent_ce, NULL TSRMLS_CC);
-/* entry = zend_register_internal_ns_class(&ce, parent_ce, ns, NULL TSRMLS_CC); */
#define DOM_GET_OBJ(__ptr, __id, __prtype) { \
dom_object *intern = (dom_object *)zend_object_store_get_object(__id TSRMLS_CC); \