Skip to content

Commit

Permalink
fix various "Class entry requested for an object without PHP class" m…
Browse files Browse the repository at this point in the history
…essages

when working with non-PHP objects.
# Using Z_OBJCE(object)->name is usually bad idea unless you know it's
# a pure PHP object
  • Loading branch information
smalyshev committed Jun 27, 2005
1 parent 46fcf91 commit d5a1296
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 27 deletions.
36 changes: 33 additions & 3 deletions Zend/zend_API.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -248,6 +256,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)
{
Expand Down Expand Up @@ -2197,7 +2218,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);
Expand Down Expand Up @@ -2279,7 +2305,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);
Expand Down
1 change: 1 addition & 0 deletions Zend/zend_API.h
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,7 @@ ZEND_API void zend_update_property_stringl(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)

Expand Down
36 changes: 13 additions & 23 deletions Zend/zend_builtin_functions.c
Original file line number Diff line number Diff line change
Expand Up @@ -525,6 +525,7 @@ ZEND_FUNCTION(get_class)
zval **arg;
char *name = "";
zend_uint name_len = 0;
int dup;

if (!ZEND_NUM_ARGS()) {
if (EG(scope)) {
Expand All @@ -540,19 +541,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);
}
/* }}} */

Expand Down Expand Up @@ -1735,13 +1726,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;
Expand Down Expand Up @@ -1913,12 +1905,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) {
Expand Down Expand Up @@ -2066,7 +2057,6 @@ ZEND_FUNCTION(get_extension_funcs)
}
/* }}} */


/*
* Local variables:
* tab-width: 4
Expand Down
12 changes: 11 additions & 1 deletion Zend/zend_exceptions.c
Original file line number Diff line number Diff line change
Expand Up @@ -359,10 +359,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;
}
Expand Down

0 comments on commit d5a1296

Please sign in to comment.