From c7200842cce5e028d2903c3bf2f9ba80afbe65d9 Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Mon, 27 Jun 2005 17:42:06 +0000 Subject: [PATCH] fix various "Class entry requested for an object without PHP class" messages when working with non-PHP objects. # Using Z_OBJCE(object)->name is usually bad idea unless you know it's # a pure PHP object --- Zend/zend_API.c | 36 ++++++++++++++++++++++++++++++++--- Zend/zend_API.h | 1 + Zend/zend_builtin_functions.c | 36 +++++++++++++---------------------- Zend/zend_exceptions.c | 12 +++++++++++- 4 files changed, 58 insertions(+), 27 deletions(-) diff --git a/Zend/zend_API.c b/Zend/zend_API.c index 4f4471d0b1..560af38642 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -156,11 +156,19 @@ ZEND_API int _zend_get_parameters_array_ex(int param_count, zval ***argument_arr if (EG(ze1_compatibility_mode) && Z_TYPE_PP(value) == IS_OBJECT) { zval *value_ptr; + char *class_name; + zend_uint class_name_len; + int dup; + + dup = zend_get_object_classname(*value, &class_name, &class_name_len TSRMLS_CC); ALLOC_ZVAL(value_ptr); *value_ptr = **value; INIT_PZVAL(value_ptr); - zend_error(E_STRICT, "Implicit cloning object of class '%s' because of 'zend.ze1_compatibility_mode'", Z_OBJCE_PP(value)->name); + zend_error(E_STRICT, "Implicit cloning object of class '%s' because of 'zend.ze1_compatibility_mode'", class_name); + if(!dup) { + efree(class_name); + } value_ptr->value.obj = Z_OBJ_HANDLER_PP(value, clone_obj)(*value TSRMLS_CC); zval_ptr_dtor(value); *value = value_ptr; @@ -226,6 +234,19 @@ ZEND_API zend_class_entry *zend_get_class_entry(zval *zobject TSRMLS_DC) } } +ZEND_API int zend_get_object_classname(zval *object, char **class_name, zend_uint *class_name_len TSRMLS_DC) +{ + if (Z_OBJ_HT_P(object)->get_class_name == NULL || + Z_OBJ_HT_P(object)->get_class_name(object, class_name, class_name_len, 0 TSRMLS_CC) != SUCCESS) { + zend_class_entry *ce = Z_OBJCE_P(object); + + *class_name = ce->name; + *class_name_len = ce->name_length; + return 1; + } + return 0; +} + static char *zend_parse_arg_impl(zval **arg, va_list *va, char **spec TSRMLS_DC) { @@ -2022,7 +2043,12 @@ ZEND_API void zend_update_property(zend_class_entry *scope, zval *object, char * EG(scope) = scope; if (!Z_OBJ_HT_P(object)->write_property) { - zend_error(E_CORE_ERROR, "Property %s of class %s cannot be updated", Z_OBJCE_P(object)->name, name); + char *class_name; + zend_uint class_name_len; + + zend_get_object_classname(object, &class_name, &class_name_len TSRMLS_CC); + + zend_error(E_CORE_ERROR, "Property %s of class %s cannot be updated", name, class_name); } ZVAL_STRINGL(&property, name, name_length, 0); Z_OBJ_HT_P(object)->write_property(object, &property, value TSRMLS_CC); @@ -2071,7 +2097,11 @@ ZEND_API zval *zend_read_property(zend_class_entry *scope, zval *object, char *n EG(scope) = scope; if (!Z_OBJ_HT_P(object)->read_property) { - zend_error(E_CORE_ERROR, "Property %s of class %s cannot be read", Z_OBJCE_P(object)->name, name); + char *class_name; + zend_uint class_name_len; + + zend_get_object_classname(object, &class_name, &class_name_len TSRMLS_CC); + zend_error(E_CORE_ERROR, "Property %s of class %s cannot be read", name, class_name); } ZVAL_STRINGL(&property, name, name_length, 0); value = Z_OBJ_HT_P(object)->read_property(object, &property, silent TSRMLS_CC); diff --git a/Zend/zend_API.h b/Zend/zend_API.h index b73a4e7038..0e226421b2 100644 --- a/Zend/zend_API.h +++ b/Zend/zend_API.h @@ -201,6 +201,7 @@ ZEND_API void zend_update_property_string(zend_class_entry *scope, zval *object, ZEND_API zval *zend_read_property(zend_class_entry *scope, zval *object, char *name, int name_length, zend_bool silent TSRMLS_DC); ZEND_API zend_class_entry *zend_get_class_entry(zval *zobject TSRMLS_DC); +ZEND_API int zend_get_object_classname(zval *object, char **class_name, zend_uint *class_name_len TSRMLS_DC); #define getThis() (this_ptr) diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index fd157c2323..7513e62f9a 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -523,6 +523,7 @@ ZEND_FUNCTION(get_class) zval **arg; char *name = ""; zend_uint name_len = 0; + int dup; if (!ZEND_NUM_ARGS()) { if (EG(scope)) { @@ -538,19 +539,9 @@ ZEND_FUNCTION(get_class) RETURN_FALSE; } - if (Z_OBJ_HT_PP(arg)->get_class_name == NULL || - Z_OBJ_HT_PP(arg)->get_class_name(*arg, &name, &name_len, 0 TSRMLS_CC) != SUCCESS) { - zend_class_entry *ce; + dup = zend_get_object_classname(*arg, &name, &name_len TSRMLS_CC); - ce = zend_get_class_entry(*arg TSRMLS_CC); - if (!ce) { - RETURN_FALSE; - } - - RETURN_STRINGL(ce->name, ce->name_length, 1); - } - - RETURN_STRINGL(name, name_len, 0); + RETURN_STRINGL(name, name_len, dup); } /* }}} */ @@ -1642,13 +1633,14 @@ ZEND_FUNCTION(debug_print_backtrace) class_name = ptr->function_state.function->common.scope->name; } else { zend_uint class_name_len; - if (Z_OBJ_HT_P(ptr->object)->get_class_name == NULL || - Z_OBJ_HT_P(ptr->object)->get_class_name(ptr->object, &class_name, &class_name_len, 0 TSRMLS_CC) != SUCCESS) { - class_name = Z_OBJCE(*ptr->object)->name; - } else { + int dup; + + dup = zend_get_object_classname(ptr->object, &class_name, &class_name_len TSRMLS_CC); + if(!dup) { free_class_name = class_name; } } + call_type = "->"; } else if (ptr->function_state.function->common.scope) { class_name = ptr->function_state.function->common.scope->name; @@ -1820,12 +1812,11 @@ ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last TSRML add_assoc_string_ex(stack_frame, "class", sizeof("class"), ptr->function_state.function->common.scope->name, 1); } else { zend_uint class_name_len; - if (Z_OBJ_HT_P(ptr->object)->get_class_name == NULL || - Z_OBJ_HT_P(ptr->object)->get_class_name(ptr->object, &class_name, &class_name_len, 0 TSRMLS_CC) != SUCCESS) { - add_assoc_string_ex(stack_frame, "class", sizeof("class"), Z_OBJCE(*ptr->object)->name, 1); - } else { - add_assoc_string_ex(stack_frame, "class", sizeof("class"), class_name, 0); - } + int dup; + + dup = zend_get_object_classname(ptr->object, &class_name, &class_name_len TSRMLS_CC); + add_assoc_string_ex(stack_frame, "class", sizeof("class"), class_name, dup); + } add_assoc_string_ex(stack_frame, "type", sizeof("type"), "->", 1); } else if (ptr->function_state.function->common.scope) { @@ -1973,7 +1964,6 @@ ZEND_FUNCTION(get_extension_funcs) } /* }}} */ - /* * Local variables: * tab-width: 4 diff --git a/Zend/zend_exceptions.c b/Zend/zend_exceptions.c index 6f24d19b21..2a9d0c0825 100644 --- a/Zend/zend_exceptions.c +++ b/Zend/zend_exceptions.c @@ -298,10 +298,20 @@ static int _build_trace_args(zval **arg, int num_args, va_list args, zend_hash_k TRACE_APPEND_STR("Array, "); break; case IS_OBJECT: { + char *class_name; + zend_uint class_name_len; + int dup; TSRMLS_FETCH(); TRACE_APPEND_STR("Object("); - TRACE_APPEND_STRL(Z_OBJCE_PP(arg)->name, strlen(Z_OBJCE_PP(arg)->name)); + + dup = zend_get_object_classname(*arg, &class_name, &class_name_len TSRMLS_CC); + + TRACE_APPEND_STRL(class_name, class_name_len); + if(!dup) { + efree(class_name); + } + TRACE_APPEND_STR("), "); break; } -- 2.50.1