Fix memory leaks

This commit is contained in:
John Coggeshall 2003-08-06 00:01:22 +00:00
parent cc011660e7
commit ea72aabfe2
2 changed files with 697 additions and 681 deletions

View file

@ -52,10 +52,7 @@ extern zend_module_entry tidy_module_entry;
#define TIDY_RV_FALSE(__t) __t->type = IS_BOOL; __t->value.lval = FALSE
#define TIDY_RV_TRUE(__t) __t->type = IS_BOOL; __t->value.lval = TRUE
#define TIDY_IS_TN_PROP(_p) zend_hash_exists(TIDY_G(tn_prop), #_p, strlen(#_p))
#define TIDY_IS_TA_PROP(_p) zend_hash_exists(TIDY_G(ta_prop), #_p, strlen(#_p))
#define REMOVE_NEWLINE(_z) _z->value.str.val[_z->value.str.len-1] = '\0';
#define REMOVE_NEWLINE(_z) _z->value.str.val[_z->value.str.len-1] = '\0'; _z->value.str.len--;
#define TIDY_TAG_CONST(tag) REGISTER_LONG_CONSTANT("TIDY_TAG_" #tag, TidyTag_##tag, CONST_CS | CONST_PERSISTENT)
#define TIDY_ATTR_CONST(attr) REGISTER_LONG_CONSTANT("TIDY_ATTR_" #attr, TidyAttr_##attr, CONST_CS | CONST_PERSISTENT)
@ -82,7 +79,7 @@ struct _PHPTidyObj {
TidyAttr attr;
PHPTidyDoc *tdoc;
unsigned int type;
zval *obj_parent;
PHPTidyObj *parent;
unsigned int refcount;
};
@ -121,38 +118,38 @@ PHP_FUNCTION(tidy_get_html);
PHP_FUNCTION(tidy_get_head);
PHP_FUNCTION(tidy_get_body);
static void php_tidy_obj_clone(void *, void ** TSRMLS_DC);
static void php_tidy_obj_dtor(void *, zend_object_handle TSRMLS_DC);
void php_tidy_obj_clone(void *, void ** TSRMLS_DC);
void php_tidy_obj_dtor(void *, zend_object_handle TSRMLS_DC);
zend_object_value php_tidy_create_obj(zend_class_entry * TSRMLS_DC);
static zend_object_value php_tidy_register_object(PHPTidyObj *intern TSRMLS_DC);
static zval *_php_tidy_create_obj_zval(unsigned int objtype,
zend_object_value php_tidy_register_object(PHPTidyObj *intern TSRMLS_DC);
zval *_php_tidy_create_obj_zval(unsigned int objtype,
PHPTidyObj *parent,
void *data
TSRMLS_DC);
static void _php_tidy_create_obj(zval *return_value,
void _php_tidy_create_obj(zval *return_value,
unsigned int objtype,
PHPTidyObj *parent,
void *data
TSRMLS_DC);
/* object handlers */
static zval * tidy_property_read(zval *object, zval *member, zend_bool silent TSRMLS_DC);
static void tidy_property_write(zval *obj, zval *member, zval *value TSRMLS_DC);
static zval ** tidy_property_get_ptr(zval *obj, zval *member TSRMLS_DC);
static int tidy_property_exists(zval *object, zval *member, int check_empty TSRMLS_DC);
static void tidy_property_delete(zval *obj, zval *member TSRMLS_DC);
static HashTable * tidy_get_properties(zval *object TSRMLS_DC);
static union _zend_function * tidy_get_method(zval *obj, char *method, int method_len TSRMLS_DC);
static int tidy_call_method(char *method, INTERNAL_FUNCTION_PARAMETERS);
static union _zend_function * tidy_get_constructor(zval *obj TSRMLS_DC);
static zend_class_entry * tidy_get_class_entry(zval *obj TSRMLS_DC);
static int tidy_get_class_name(zval *obj, char **class_name, zend_uint *name_len, int parent TSRMLS_DC);
static int tidy_objects_compare(zval *obj_one, zval *obj_two TSRMLS_DC);
static void tidy_object_cast(zval *readobj, zval *writeobj, int type, int should_free TSRMLS_DC);
static void tidy_write_dim(zval *object, zval *offset, zval *value TSRMLS_DC);
static void tidy_del_dim(zval *object, zval *offset TSRMLS_DC);
static zval *tidy_read_dim(zval *object, zval *offset TSRMLS_DC);
zval * tidy_property_read(zval *object, zval *member, zend_bool silent TSRMLS_DC);
void tidy_property_write(zval *obj, zval *member, zval *value TSRMLS_DC);
zval ** tidy_property_get_ptr(zval *obj, zval *member TSRMLS_DC);
int tidy_property_exists(zval *object, zval *member, int check_empty TSRMLS_DC);
void tidy_property_delete(zval *obj, zval *member TSRMLS_DC);
HashTable * tidy_get_properties(zval *object TSRMLS_DC);
union _zend_function * tidy_get_method(zval *obj, char *method, int method_len TSRMLS_DC);
int tidy_call_method(char *method, INTERNAL_FUNCTION_PARAMETERS);
union _zend_function * tidy_get_constructor(zval *obj TSRMLS_DC);
zend_class_entry * tidy_get_class_entry(zval *obj TSRMLS_DC);
int tidy_get_class_name(zval *obj, char **class_name, zend_uint *name_len, int parent TSRMLS_DC);
int tidy_objects_compare(zval *obj_one, zval *obj_two TSRMLS_DC);
void tidy_object_cast(zval *readobj, zval *writeobj, int type, int should_free TSRMLS_DC);
void tidy_write_dim(zval *object, zval *offset, zval *value TSRMLS_DC);
void tidy_del_dim(zval *object, zval *offset TSRMLS_DC);
zval *tidy_read_dim(zval *object, zval *offset TSRMLS_DC);
zend_bool _php_tidy_attr_call_method(char *method, INTERNAL_FUNCTION_PARAMETERS);
zend_bool _php_tidy_node_call_method(char *method, INTERNAL_FUNCTION_PARAMETERS);

View file

@ -99,7 +99,7 @@ zend_module_entry tidy_module_entry = {
#if ZEND_MODULE_API_NO >= 20010901
STANDARD_MODULE_HEADER,
#endif
"Tidy",
"tidy",
tidy_functions,
PHP_MINIT(tidy),
PHP_MSHUTDOWN(tidy),
@ -152,15 +152,16 @@ PHPTidyObj *php_tidy_new(TSRMLS_DC) {
intern->attr = NULL;
intern->type = PHP_IS_TIDYUNDEF;
intern->tdoc = NULL;
intern->parent = NULL;
intern->obj.properties = emalloc(sizeof(HashTable));
ALLOC_HASHTABLE(intern->obj.properties);
zend_hash_init(intern->obj.properties, 0, NULL, ZVAL_PTR_DTOR, 0);
return intern;
}
static zval *_php_tidy_create_obj_zval(unsigned int objtype,
zval *_php_tidy_create_obj_zval(unsigned int objtype,
PHPTidyObj *parent,
void *data
TSRMLS_DC) {
@ -172,18 +173,25 @@ static zval *_php_tidy_create_obj_zval(unsigned int objtype,
return return_value;
}
static void _php_tidy_create_obj(zval *return_value,
void _php_tidy_create_obj(zval *return_value,
unsigned int objtype,
PHPTidyObj *parent,
void *data
TSRMLS_DC) {
PHPTidyObj *retobj;
PHPTidyObj *retobj, *t;
retobj = php_tidy_new();
retobj->tdoc = parent->tdoc;
retobj->type = objtype;
retobj->refcount = 1;
retobj->parent = parent;
t = retobj;
while((t = t->parent)) {
t->refcount++;
}
parent->refcount++;
switch(objtype) {
@ -204,7 +212,7 @@ static void _php_tidy_create_obj(zval *return_value,
}
static zend_object_value php_tidy_register_object(PHPTidyObj *intern TSRMLS_DC) {
zend_object_value php_tidy_register_object(PHPTidyObj *intern TSRMLS_DC) {
zend_object_value retval;
@ -233,11 +241,17 @@ void dtor_TidyDoc(zend_rsrc_list_entry *rsrc TSRMLS_DC) {
}
static void php_tidy_obj_dtor(void *object, zend_object_handle handle TSRMLS_DC) {
void php_tidy_obj_dtor(void *object, zend_object_handle handle TSRMLS_DC) {
PHPTidyObj *o = (PHPTidyObj *)object;
if(--o->refcount == 0) {
do {
o->refcount--;
} while((o = o->parent));
o = (PHPTidyObj *)object;
if(o->refcount <= 0) {
/* We don't free anything else here from
PHPTidyObj, they are all pointers
to internal TidyNode structs, which
@ -245,12 +259,22 @@ static void php_tidy_obj_dtor(void *object, zend_object_handle handle TSRMLS_DC)
destroied by TidyRelease()
*/
// zend_hash_destroy(o->obj.properties);
// FREE_HASHTABLE(o->obj.properties);
zend_objects_destroy_object(&o->obj, handle TSRMLS_CC);
o->node = NULL;
o->attr = NULL;
o->tdoc = NULL;
o->type = PHP_IS_TIDYUNDEF;
o->parent = NULL;
efree(o);
}
}
static void php_tidy_obj_clone(void *object, void **object_clone TSRMLS_DC) {
void php_tidy_obj_clone(void *object, void **object_clone TSRMLS_DC) {
PHPTidyObj *intern = (PHPTidyObj *) object;
PHPTidyObj **intern_clone = (PHPTidyObj **) object_clone;
@ -269,7 +293,7 @@ static void php_tidy_obj_clone(void *object, void **object_clone TSRMLS_DC) {
}
static void php_tidy_init_globals(zend_tidy_globals *tidy_globals) {
void php_tidy_init_globals(zend_tidy_globals *tidy_globals) {
/* No globals for now */
}
@ -1135,29 +1159,29 @@ PHP_FUNCTION(tidy_get_body) {
}
/* }}} */
static void tidy_property_delete(zval *obj, zval *member TSRMLS_DC) {}
static void tidy_property_write(zval *obj, zval *member, zval *value TSRMLS_DC) {}
static void tidy_object_cast(zval *readobj, zval *writeobj, int type, int should_free TSRMLS_DC) {}
static union _zend_function * tidy_get_constructor(zval *obj TSRMLS_DC) { return NULL; }
static void tidy_write_dim(zval *object, zval *offset, zval *value TSRMLS_DC) {}
static void tidy_del_dim(zval *object, zval *offset TSRMLS_DC) {}
static zval *tidy_read_dim(zval *object, zval *offset TSRMLS_DC) {
void tidy_property_delete(zval *obj, zval *member TSRMLS_DC) {}
void tidy_property_write(zval *obj, zval *member, zval *value TSRMLS_DC) {}
void tidy_object_cast(zval *readobj, zval *writeobj, int type, int should_free TSRMLS_DC) {}
union _zend_function * tidy_get_constructor(zval *obj TSRMLS_DC) { return NULL; }
void tidy_write_dim(zval *object, zval *offset, zval *value TSRMLS_DC) {}
void tidy_del_dim(zval *object, zval *offset TSRMLS_DC) {}
zval *tidy_read_dim(zval *object, zval *offset TSRMLS_DC) {
return EG(uninitialized_zval_ptr);
}
static zend_class_entry * tidy_get_class_entry(zval *obj TSRMLS_DC) {
zend_class_entry * tidy_get_class_entry(zval *obj TSRMLS_DC) {
return php_tidy_ce;
}
static zval ** tidy_property_get_ptr(zval *obj, zval *member TSRMLS_DC) {
zval ** tidy_property_get_ptr(zval *obj, zval *member TSRMLS_DC) {
zval **p_ptr;
zval *p;
/* How to fix this memleak? */
p_ptr = emalloc(sizeof(zval **));
//p_ptr = emalloc(sizeof(zval **));
p = tidy_property_read(obj, member, 0 TSRMLS_CC);
@ -1167,7 +1191,7 @@ static zval ** tidy_property_get_ptr(zval *obj, zval *member TSRMLS_DC) {
}
static zval * tidy_property_read(zval *object, zval *member, zend_bool silent TSRMLS_DC) {
zval * tidy_property_read(zval *object, zval *member, zend_bool silent TSRMLS_DC) {
PHPTidyObj *obj = php_tidy_fetch_object(object);
zval *return_value, *temp;
@ -1228,14 +1252,11 @@ static zval * tidy_property_read(zval *object, zval *member, zend_bool silent TS
if(tempattr) {
temp = _php_tidy_create_obj_zval(PHP_IS_TIDYATTR, obj, tempattr TSRMLS_CC);
temp->refcount--;
add_next_index_zval(return_value, temp);
while((tempattr = tidyAttrNext(tempattr))) {
temp = _php_tidy_create_obj_zval(PHP_IS_TIDYATTR, obj, tempattr TSRMLS_CC);
add_next_index_zval(return_value, temp);
}
}
@ -1247,13 +1268,10 @@ static zval * tidy_property_read(zval *object, zval *member, zend_bool silent TS
temp = _php_tidy_create_obj_zval(PHP_IS_TIDYNODE, obj, tempnode TSRMLS_CC);
add_next_index_zval(return_value, temp);
while((tempnode = tidyGetNext(tempnode))) {
temp = _php_tidy_create_obj_zval(PHP_IS_TIDYNODE, obj, tempnode TSRMLS_CC);
temp->refcount--;
add_next_index_zval(return_value, temp);
}
}
@ -1266,6 +1284,7 @@ static zval * tidy_property_read(zval *object, zval *member, zend_bool silent TS
}
break;
case PHP_IS_TIDYATTR:
if(!strcmp(name, "name")) {
@ -1293,12 +1312,12 @@ static zval * tidy_property_read(zval *object, zval *member, zend_bool silent TS
}
static int tidy_property_exists(zval *object, zval *member, int check_empty TSRMLS_DC) {
int tidy_property_exists(zval *object, zval *member, int check_empty TSRMLS_DC) {
return TRUE;
}
static HashTable * tidy_get_properties(zval *object TSRMLS_DC) {
HashTable * tidy_get_properties(zval *object TSRMLS_DC) {
zend_object *zobj;
zobj = zend_objects_get_address(object TSRMLS_CC);
@ -1306,7 +1325,7 @@ static HashTable * tidy_get_properties(zval *object TSRMLS_DC) {
}
static union _zend_function * tidy_get_method(zval *obj, char *method, int method_len TSRMLS_DC) {
union _zend_function * tidy_get_method(zval *obj, char *method, int method_len TSRMLS_DC) {
zend_internal_function *f;
@ -1315,8 +1334,6 @@ static union _zend_function * tidy_get_method(zval *obj, char *method, int metho
f->arg_types = NULL;
f->scope = php_tidy_ce;
f->fn_flags = 0;
/* How to fix this memleak? */
f->function_name = estrndup(method, method_len);
return (union _zend_function *) f;
@ -1325,9 +1342,11 @@ static union _zend_function * tidy_get_method(zval *obj, char *method, int metho
zend_bool _php_tidy_node_call_method(char *method, INTERNAL_FUNCTION_PARAMETERS) {
PHPTidyObj *obj = php_tidy_fetch_object(getThis());
zend_internal_function *func = (zend_internal_function *)EG(function_state_ptr)->function;
PHPTidyObj *newobj;
TidyNode tempnode;
TidyAttr tempattr;
zend_bool retval = TRUE;
int param;
@ -1511,13 +1530,13 @@ zend_bool _php_tidy_node_call_method(char *method, INTERNAL_FUNCTION_PARAMETERS)
}
} else {
return FALSE;
retval = FALSE;
}
}
return TRUE;
efree(func->function_name);
efree(func);
return retval;
}
@ -1547,7 +1566,7 @@ zend_bool _php_tidy_attr_call_method(char *method, INTERNAL_FUNCTION_PARAMETERS)
return TRUE;
}
static int tidy_call_method(char *method, INTERNAL_FUNCTION_PARAMETERS) {
int tidy_call_method(char *method, INTERNAL_FUNCTION_PARAMETERS) {
PHPTidyObj *obj = php_tidy_fetch_object(getThis());
@ -1567,7 +1586,7 @@ static int tidy_call_method(char *method, INTERNAL_FUNCTION_PARAMETERS) {
return FALSE;
}
static int tidy_get_class_name(zval *obj, char **class_name, zend_uint *name_len, int parent TSRMLS_DC) {
int tidy_get_class_name(zval *obj, char **class_name, zend_uint *name_len, int parent TSRMLS_DC) {
PHPTidyObj *object = php_tidy_fetch_object(obj);
@ -1595,7 +1614,7 @@ static int tidy_get_class_name(zval *obj, char **class_name, zend_uint *name_len
return TRUE;
}
static int tidy_objects_compare(zval *obj_one, zval *obj_two TSRMLS_DC) {
int tidy_objects_compare(zval *obj_one, zval *obj_two TSRMLS_DC) {
PHPTidyObj *obj1, *obj2;