diff options
-rw-r--r-- | Zend/zend.c | 39 | ||||
-rw-r--r-- | Zend/zend_object_handlers.c | 15 | ||||
-rw-r--r-- | Zend/zend_object_handlers.h | 5 | ||||
-rw-r--r-- | Zend/zend_operators.h | 3 | ||||
-rw-r--r-- | ext/simplexml/simplexml.c | 78 | ||||
-rw-r--r-- | ext/standard/var.c | 8 |
6 files changed, 96 insertions, 52 deletions
diff --git a/Zend/zend.c b/Zend/zend.c index 1921b07a3f..e7767ceadf 100644 --- a/Zend/zend.c +++ b/Zend/zend.c @@ -317,7 +317,7 @@ ZEND_API void zend_print_flat_zval_r(zval *expr TSRMLS_DC) HashTable *properties = NULL; char *class_name = NULL; zend_uint clen; - + if (Z_OBJ_HANDLER_P(expr, get_class_name)) { Z_OBJ_HANDLER_P(expr, get_class_name)(expr, &class_name, &clen, 0 TSRMLS_CC); } @@ -367,10 +367,11 @@ ZEND_API void zend_print_zval_r_ex(zend_write_func_t write_func, zval *expr, int break; case IS_OBJECT: { - HashTable *properties = NULL; + HashTable *properties; char *class_name = NULL; zend_uint clen; - + int is_temp; + if (Z_OBJ_HANDLER_P(expr, get_class_name)) { Z_OBJ_HANDLER_P(expr, get_class_name)(expr, &class_name, &clen, 0 TSRMLS_CC); } @@ -383,17 +384,19 @@ ZEND_API void zend_print_zval_r_ex(zend_write_func_t write_func, zval *expr, int if (class_name) { efree(class_name); } - if (Z_OBJ_HANDLER_P(expr, get_properties)) { - properties = Z_OBJPROP_P(expr); + if ((properties = Z_OBJDEBUG_P(expr, is_temp)) == NULL) { + break; } - if (properties) { - if (++properties->nApplyCount>1) { - ZEND_PUTS_EX(" *RECURSION*"); - properties->nApplyCount--; - return; - } - print_hash(write_func, properties, indent, 1 TSRMLS_CC); + if (++properties->nApplyCount>1) { + ZEND_PUTS_EX(" *RECURSION*"); properties->nApplyCount--; + return; + } + print_hash(write_func, properties, indent, 1 TSRMLS_CC); + properties->nApplyCount--; + if (is_temp) { + zend_hash_destroy(properties); + efree(properties); } break; } @@ -711,7 +714,7 @@ void zend_post_startup(TSRMLS_D) short_tags_default = CG(short_tags); ct_pass_ref_default = CG(allow_call_time_pass_reference); extended_info_default = CG(extended_info); - + zend_destroy_rsrc_list(&EG(persistent_list) TSRMLS_CC); free(compiler_globals->function_table); free(compiler_globals->class_table); @@ -839,7 +842,7 @@ void zend_deactivate_modules(TSRMLS_D) } zend_end_try(); } -void zend_call_destructors(TSRMLS_D) +void zend_call_destructors(TSRMLS_D) { zend_try { shutdown_destructors(TSRMLS_C); @@ -1026,11 +1029,11 @@ ZEND_API void zend_error(int type, const char *format, ...) orig_user_error_handler = EG(user_error_handler); EG(user_error_handler) = NULL; - + /* User error handler may include() additinal PHP files. * If an error was generated during comilation PHP will compile - * such scripts recursivly, but some CG() variables may be - * inconsistent. */ + * such scripts recursivly, but some CG() variables may be + * inconsistent. */ in_compilation = zend_is_compiling(TSRMLS_C); if (in_compilation) { @@ -1056,7 +1059,7 @@ ZEND_API void zend_error(int type, const char *format, ...) if (!EG(user_error_handler)) { EG(user_error_handler) = orig_user_error_handler; - } + } else { zval_ptr_dtor(&orig_user_error_handler); } diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index e0260c1a65..b71df7c8ec 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -42,14 +42,14 @@ set, we call __set handler. If it fails, we do not change the array. for both handlers above, when we are inside __get/__set, no further calls for - __get/__set for this property of this object will be made, to prevent endless + __get/__set for this property of this object will be made, to prevent endless recursion and enable accessors to change properties array. if we have __call and method which is not part of the class function table is called, we cal __call handler. */ -static HashTable *zend_std_get_properties(zval *object TSRMLS_DC) +ZEND_API HashTable *zend_std_get_properties(zval *object TSRMLS_DC) { zend_object *zobj; zobj = Z_OBJ_P(object); @@ -316,7 +316,7 @@ zval *zend_std_read_property(zval *object, zval *member, int type TSRMLS_DC) #if DEBUG_OBJECT_HANDLERS fprintf(stderr, "Read object #%d property: %s\n", Z_OBJ_HANDLE_P(object), Z_STRVAL_P(member)); -#endif +#endif /* make zend_get_property_info silent if we have getter - we may want to use it */ property_info = zend_get_property_info(zobj->ce, member, (zobj->ce->__get != NULL) TSRMLS_CC); @@ -758,11 +758,11 @@ static union _zend_function *zend_std_get_method(zval **object_ptr, char *method zend_function *fbc; char *lc_method_name; zval *object = *object_ptr; - + lc_method_name = do_alloca(method_len+1); /* Create a zend_copy_str_tolower(dest, src, src_length); */ zend_str_tolower_copy(lc_method_name, method_name, method_len); - + zobj = Z_OBJ_P(object); if (zend_hash_find(&zobj->ce->function_table, lc_method_name, method_len+1, (void **)&fbc) == FAILURE) { free_alloca(lc_method_name); @@ -830,7 +830,7 @@ ZEND_API void zend_std_callstatic_user_call(INTERNAL_FUNCTION_PARAMETERS) /* {{{ zval *method_name_ptr, *method_args_ptr; zval *method_result_ptr = NULL; zend_class_entry *ce = EG(scope); - + ALLOC_ZVAL(method_args_ptr); INIT_PZVAL(method_args_ptr); array_init(method_args_ptr); @@ -883,7 +883,7 @@ ZEND_API zend_function *zend_std_get_static_method(zend_class_entry *ce, char *f callstatic_user_call->arg_info = NULL; callstatic_user_call->num_args = 0; callstatic_user_call->scope = ce; - callstatic_user_call->fn_flags = ZEND_ACC_STATIC | ZEND_ACC_PUBLIC; + callstatic_user_call->fn_flags = ZEND_ACC_STATIC | ZEND_ACC_PUBLIC; callstatic_user_call->function_name = estrndup(function_name_strval, function_name_strlen); callstatic_user_call->pass_rest_by_reference = 0; callstatic_user_call->return_reference = ZEND_RETURN_VALUE; @@ -1202,6 +1202,7 @@ ZEND_API zend_object_handlers std_object_handlers = { zend_std_compare_objects, /* compare_objects */ zend_std_cast_object_tostring, /* cast_object */ NULL, /* count_elements */ + NULL, /* get_debug_info */ }; /* diff --git a/Zend/zend_object_handlers.h b/Zend/zend_object_handlers.h index 8c27ae6340..83dd72356c 100644 --- a/Zend/zend_object_handlers.h +++ b/Zend/zend_object_handlers.h @@ -80,6 +80,8 @@ typedef void (*zend_object_unset_dimension_t)(zval *object, zval *offset TSRMLS_ /* Used to get hash of the properties of the object, as hash of zval's */ typedef HashTable *(*zend_object_get_properties_t)(zval *object TSRMLS_DC); +typedef HashTable *(*zend_object_get_debug_info_t)(zval *object, int *is_temp TSRMLS_DC); + /* Used to call methods */ /* args on stack! */ /* Andi - EX(fbc) (function being called) needs to be initialized already in the INIT fcall opcode so that the parameters can be parsed the right way. We need to add another callback for this. @@ -132,6 +134,7 @@ struct _zend_object_handlers { zend_object_compare_t compare_objects; zend_object_cast_t cast_object; zend_object_count_elements_t count_elements; + zend_object_get_debug_info_t get_debug_info; }; extern ZEND_API zend_object_handlers std_object_handlers; @@ -143,6 +146,8 @@ ZEND_API zend_bool zend_std_unset_static_property(zend_class_entry *ce, char *pr ZEND_API union _zend_function *zend_std_get_constructor(zval *object TSRMLS_DC); ZEND_API struct _zend_property_info *zend_get_property_info(zend_class_entry *ce, zval *member, int silent TSRMLS_DC); +ZEND_API HashTable *zend_std_get_properties(zval *object TSRMLS_DC); +ZEND_API HashTable *zend_std_get_debug_info(zval *object, int *is_temp TSRMLS_DC); ZEND_API int zend_std_cast_object_tostring(zval *readobj, zval *writeobj, int type TSRMLS_DC); diff --git a/Zend/zend_operators.h b/Zend/zend_operators.h index c20c57088c..f5c6251ca7 100644 --- a/Zend/zend_operators.h +++ b/Zend/zend_operators.h @@ -387,6 +387,7 @@ END_EXTERN_C() #define Z_OBJPROP(zval) Z_OBJ_HT((zval))->get_properties(&(zval) TSRMLS_CC) #define Z_OBJ_HANDLER(zval, hf) Z_OBJ_HT((zval))->hf #define Z_RESVAL(zval) (zval).value.lval +#define Z_OBJDEBUG(zval,is_tmp) (Z_OBJ_HANDLER((zval),get_debug_info)?Z_OBJ_HANDLER((zval),get_debug_info)(&(zval),&is_tmp TSRMLS_CC):(is_tmp=0,Z_OBJ_HANDLER((zval),get_properties)?Z_OBJPROP(zval):NULL)) #define Z_LVAL_P(zval_p) Z_LVAL(*zval_p) #define Z_BVAL_P(zval_p) Z_BVAL(*zval_p) @@ -401,6 +402,7 @@ END_EXTERN_C() #define Z_OBJ_HANDLE_P(zval_p) Z_OBJ_HANDLE(*zval_p) #define Z_OBJ_HT_P(zval_p) Z_OBJ_HT(*zval_p) #define Z_OBJ_HANDLER_P(zval_p, h) Z_OBJ_HANDLER(*zval_p, h) +#define Z_OBJDEBUG_P(zval_p,is_tmp) Z_OBJDEBUG(*zval_p,is_tmp) #define Z_LVAL_PP(zval_pp) Z_LVAL(**zval_pp) #define Z_BVAL_PP(zval_pp) Z_BVAL(**zval_pp) @@ -415,6 +417,7 @@ END_EXTERN_C() #define Z_OBJ_HANDLE_PP(zval_p) Z_OBJ_HANDLE(**zval_p) #define Z_OBJ_HT_PP(zval_p) Z_OBJ_HT(**zval_p) #define Z_OBJ_HANDLER_PP(zval_p, h) Z_OBJ_HANDLER(**zval_p, h) +#define Z_OBJDEBUG_PP(zval_pp,is_tmp) Z_OBJDEBUG(**zval_pp,is_tmp) #define Z_TYPE(zval) (zval).type #define Z_TYPE_P(zval_p) Z_TYPE(*zval_p) diff --git a/ext/simplexml/simplexml.c b/ext/simplexml/simplexml.c index c847df27b3..734c593df8 100644 --- a/ext/simplexml/simplexml.c +++ b/ext/simplexml/simplexml.c @@ -136,7 +136,7 @@ static inline int match_ns(php_sxe_object *sxe, xmlNodePtr node, xmlChar *name, static xmlNodePtr sxe_get_element_by_offset(php_sxe_object *sxe, long offset, xmlNodePtr node, long *cnt) /* {{{ */ { long nodendx = 0; - + if (sxe->iter.type == SXE_ITER_NONE) { if (offset == 0) { if (cnt) { @@ -161,7 +161,7 @@ static xmlNodePtr sxe_get_element_by_offset(php_sxe_object *sxe, long offset, xm next_iter: node = node->next; } - + if (cnt) { *cnt = nodendx; } @@ -275,7 +275,7 @@ static zval * sxe_prop_dim_read(zval *object, zval *member, zend_bool elements, if (sxe->iter.type == SXE_ITER_ATTRLIST) { attribs = 1; - elements = 0; + elements = 0; node = php_sxe_get_first_node(sxe, node TSRMLS_CC); attr = (xmlAttrPtr)node; test = sxe->iter.name != NULL; @@ -337,7 +337,7 @@ static zval * sxe_prop_dim_read(zval *object, zval *member, zend_bool elements, } } else if (member) { node = sxe_get_element_by_offset(sxe, Z_LVAL_P(member), node, &cnt); - } else { + } else { node = NULL; } if (node) { @@ -502,7 +502,7 @@ static void sxe_prop_dim_write(zval *object, zval *member, zval *value, zend_boo if (sxe->iter.type == SXE_ITER_ATTRLIST) { attribs = 1; - elements = 0; + elements = 0; node = php_sxe_get_first_node(sxe, node TSRMLS_CC); attr = (xmlAttrPtr)node; test = sxe->iter.name != NULL; @@ -639,7 +639,7 @@ next_iter: if (!node) { if (!member || Z_TYPE_P(member) == IS_LONG) { newnode = xmlNewTextChild(mynode->parent, mynode->ns, mynode->name, value ? (xmlChar *)Z_STRVAL_P(value) : NULL); - } else { + } else { newnode = xmlNewTextChild(mynode, mynode->ns, (xmlChar *)Z_STRVAL_P(member), value ? (xmlChar *)Z_STRVAL_P(value) : NULL); } } else if (!member || Z_TYPE_P(member) == IS_LONG) { @@ -711,6 +711,9 @@ static zval** sxe_property_get_adr(zval *object, zval *member TSRMLS_DC) /* {{{ _node_as_zval(sxe, node, return_value, type, name, sxe->iter.nsprefix, sxe->iter.isprefix TSRMLS_CC); sxe = php_sxe_fetch_object(return_value TSRMLS_CC); + if (sxe->tmp) { + zval_ptr_dtor(&sxe->tmp); + } sxe->tmp = return_value; Z_SET_ISREF_P(return_value); @@ -752,7 +755,7 @@ static int sxe_prop_dim_exists(zval *object, zval *member, int check_empty, zend if (sxe->iter.type == SXE_ITER_ATTRLIST) { attribs = 1; - elements = 0; + elements = 0; node = php_sxe_get_first_node(sxe, node TSRMLS_CC); attr = (xmlAttrPtr)node; test = sxe->iter.name != NULL; @@ -814,7 +817,7 @@ static int sxe_prop_dim_exists(zval *object, zval *member, int check_empty, zend } if (node) { exists = 1; - if (check_empty == 1 && + if (check_empty == 1 && (!node->children || (node->children->type == XML_TEXT_NODE && !node->children->next && (!node->children->content || !node->children->content[0] || !xmlStrcmp(node->children->content, "0")))) ) { exists = 0; @@ -882,7 +885,7 @@ static void sxe_prop_dim_delete(zval *object, zval *member, zend_bool elements, if (sxe->iter.type == SXE_ITER_ATTRLIST) { attribs = 1; - elements = 0; + elements = 0; node = php_sxe_get_first_node(sxe, node TSRMLS_CC); attr = (xmlAttrPtr)node; test = sxe->iter.name != NULL; @@ -978,7 +981,7 @@ static inline char * sxe_xmlNodeListGetString(xmlDocPtr doc, xmlNodePtr list, in char *res = estrdup((char*)tmp); xmlFree(tmp); - + return res; } @@ -1038,9 +1041,9 @@ static void sxe_properties_add(HashTable *rv, char *name, int namelen, zval *val } } -/* {{{ sxe_properties_get() +/* {{{ sxe_get_prop_hash() */ -static HashTable * sxe_properties_get(zval *object TSRMLS_DC) +static HashTable * sxe_get_prop_hash(zval *object, int is_debug TSRMLS_DC) /* {{{ */ { zval *value; zval *zattr; @@ -1054,7 +1057,11 @@ static HashTable * sxe_properties_get(zval *object TSRMLS_DC) sxe = php_sxe_fetch_object(object TSRMLS_CC); - if (sxe->properties) { + if (is_debug) { + ALLOC_HASHTABLE(rv); + zend_hash_init(rv, 0, NULL, ZVAL_PTR_DTOR, 0); + } + else if (sxe->properties) { zend_hash_clean(sxe->properties); rv = sxe->properties; } else { @@ -1067,7 +1074,7 @@ static HashTable * sxe_properties_get(zval *object TSRMLS_DC) if (!node) { return rv; } - if (1||sxe->iter.type != SXE_ITER_CHILD) { + if (is_debug) { if (sxe->iter.type == SXE_ITER_ELEMENT) { node = php_sxe_get_first_node(sxe, node TSRMLS_CC); } @@ -1137,6 +1144,19 @@ next_iter: } /* }}} */ +static HashTable * sxe_get_properties(zval *object TSRMLS_DC) /* {{{ */ +{ + return sxe_get_prop_hash(object, 0 TSRMLS_CC); +} +/* }}} */ + +static HashTable * sxe_get_debug_info(zval *object, int *is_temp TSRMLS_DC) /* {{{ */ +{ + *is_temp = 1; + return sxe_get_prop_hash(object, 1 TSRMLS_CC); +} +/* }}} */ + static int sxe_objects_compare(zval *object1, zval *object2 TSRMLS_DC) /* {{{ */ { php_sxe_object *sxe1; @@ -1365,13 +1385,13 @@ static void sxe_add_namespaces(php_sxe_object *sxe, xmlNodePtr node, zend_bool r { xmlAttrPtr attr; - if (node->ns) { + if (node->ns) { sxe_add_namespace_name(return_value, node->ns); } attr = node->properties; while (attr) { - if (attr->ns) { + if (attr->ns) { sxe_add_namespace_name(return_value, attr->ns); } attr = attr->next; @@ -1521,7 +1541,7 @@ SXE_METHOD(attributes) sxe = php_sxe_fetch_object(getThis() TSRMLS_CC); GET_NODE(sxe, node); - + if (sxe->iter.type == SXE_ITER_ATTRLIST) { return; /* attributes don't have attributes */ } @@ -1565,7 +1585,7 @@ SXE_METHOD(addChild) if (node == NULL) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot add child. Parent is not a permanent member of the XML tree"); - return; + return; } localname = xmlSplitQName2((xmlChar *)qname, &prefix); @@ -1704,13 +1724,17 @@ static int sxe_object_cast(zval *readobj, zval *writeobj, int type TSRMLS_DC) xmlChar *contents = NULL; xmlNodePtr node; int rv; + HashTable *prop_hash; sxe = php_sxe_fetch_object(readobj TSRMLS_CC); - + if (type == IS_BOOL) { node = php_sxe_get_first_node(sxe, NULL TSRMLS_CC); + prop_hash = sxe_get_prop_hash(readobj, 1 TSRMLS_CC); INIT_PZVAL(writeobj); - ZVAL_BOOL(writeobj, node != NULL || zend_hash_num_elements(sxe_properties_get(readobj TSRMLS_CC)) > 0); + ZVAL_BOOL(writeobj, node != NULL || zend_hash_num_elements(prop_hash) > 0); + zend_hash_destroy(prop_hash); + efree(prop_hash); return SUCCESS; } @@ -1755,7 +1779,7 @@ static int sxe_count_elements(zval *object, long *count TSRMLS_DC) /* {{{ */ sxe->iter.data = NULL; node = php_sxe_reset_iterator(sxe, 0 TSRMLS_CC); - + while (node) { (*count)++; @@ -1800,7 +1824,7 @@ static zend_object_handlers sxe_object_handlers = { sxe_property_delete, sxe_dimension_exists, sxe_dimension_delete, - sxe_properties_get, + sxe_get_properties, NULL, /* zend_get_std_object_handlers()->get_method,*/ NULL, /* zend_get_std_object_handlers()->call_method,*/ NULL, /* zend_get_std_object_handlers()->get_constructor, */ @@ -1808,7 +1832,8 @@ static zend_object_handlers sxe_object_handlers = { NULL, /* zend_get_std_object_handlers()->get_class_name,*/ sxe_objects_compare, sxe_object_cast, - sxe_count_elements + sxe_count_elements, + sxe_get_debug_info }; static zend_object_handlers sxe_ze1_object_handlers = { @@ -1824,7 +1849,7 @@ static zend_object_handlers sxe_ze1_object_handlers = { sxe_property_delete, sxe_dimension_exists, sxe_dimension_delete, - sxe_properties_get, + sxe_get_properties, NULL, /* zend_get_std_object_handlers()->get_method,*/ NULL, /* zend_get_std_object_handlers()->call_method,*/ NULL, /* zend_get_std_object_handlers()->get_constructor, */ @@ -1832,7 +1857,8 @@ static zend_object_handlers sxe_ze1_object_handlers = { NULL, /* zend_get_std_object_handlers()->get_class_name,*/ sxe_objects_compare, sxe_object_cast, - sxe_count_elements + sxe_count_elements, + sxe_get_debug_info }; static zend_object_value sxe_object_ze1_clone(zval *zobject TSRMLS_DC) @@ -2294,7 +2320,7 @@ void *simplexml_export_node(zval *object TSRMLS_DC) sxe = php_sxe_fetch_object(object TSRMLS_CC); GET_NODE(sxe, node); - return php_sxe_get_first_node(sxe, node TSRMLS_CC); + return php_sxe_get_first_node(sxe, node TSRMLS_CC); } /* {{{ proto simplemxml_element simplexml_import_dom(domNode node [, string class_name]) diff --git a/ext/standard/var.c b/ext/standard/var.c index 63e57b38b0..f9a6856634 100644 --- a/ext/standard/var.c +++ b/ext/standard/var.c @@ -98,6 +98,7 @@ PHPAPI void php_var_dump(zval **struc, int level TSRMLS_DC) char *class_name; zend_uint class_name_len; int (*php_element_dump_func)(zval**, int, va_list, zend_hash_key*); + int is_temp; if (level > 1) { php_printf("%*c", level - 1, ' '); @@ -129,9 +130,10 @@ PHPAPI void php_var_dump(zval **struc, int level TSRMLS_DC) } php_printf("%sarray(%d) {\n", COMMON, zend_hash_num_elements(myht)); php_element_dump_func = php_array_element_dump; + is_temp = 0; goto head_done; case IS_OBJECT: - myht = Z_OBJPROP_PP(struc); + myht = Z_OBJDEBUG_PP(struc, is_temp); if (myht && myht->nApplyCount > 1) { PUTS("*RECURSION*\n"); return; @@ -144,6 +146,10 @@ PHPAPI void php_var_dump(zval **struc, int level TSRMLS_DC) head_done: if (myht) { zend_hash_apply_with_arguments(myht, (apply_func_args_t) php_element_dump_func, 1, level); + if (is_temp) { + zend_hash_destroy(myht); + efree(myht); + } } if (level > 1) { php_printf("%*c", level-1, ' '); |