Update get_class_name semantics

* get_class_name is now only used for displaying the class name
   in debugging functions like var_dump, print_r, etc. It is no
   longer used in get_class() etc.
 * As it is no longer used in get_parent_class() the parent
   argument is now gone. This also fixes incorrect parent classes
   being reported in COM.
 * get_class_name is now always required (previously some places
   made it optional and some required it) and is also required
   to return a non-NULL value.
 * Remove zend_get_object_classname. This also fixes a number of
   potential leaks due to incorrect usage of this function.
This commit is contained in:
Nikita Popov 2014-10-09 19:15:07 +02:00
parent c061c82945
commit df79b9b27a
12 changed files with 32 additions and 96 deletions

View file

@ -263,19 +263,10 @@ ZEND_API void zend_print_flat_zval_r(zval *expr TSRMLS_DC) /* {{{ */
case IS_OBJECT:
{
HashTable *properties = NULL;
zend_string *class_name = NULL;
if (Z_OBJ_HANDLER_P(expr, get_class_name)) {
class_name = Z_OBJ_HANDLER_P(expr, get_class_name)(Z_OBJ_P(expr), 0 TSRMLS_CC);
}
if (class_name) {
zend_string *class_name = Z_OBJ_HANDLER_P(expr, get_class_name)(Z_OBJ_P(expr) TSRMLS_CC);
zend_printf("%s Object (", class_name->val);
} else {
zend_printf("%s Object (", "Unknown Class");
}
if (class_name) {
zend_string_release(class_name);
}
if (Z_OBJ_HANDLER_P(expr, get_properties)) {
properties = Z_OBJPROP_P(expr);
}
@ -324,21 +315,13 @@ ZEND_API void zend_print_zval_r_ex(zend_write_func_t write_func, zval *expr, int
case IS_OBJECT:
{
HashTable *properties;
zend_string *class_name = NULL;
int is_temp;
if (Z_OBJ_HANDLER_P(expr, get_class_name)) {
class_name = Z_OBJ_HANDLER_P(expr, get_class_name)(Z_OBJ_P(expr), 0 TSRMLS_CC);
}
if (class_name) {
zend_string *class_name = Z_OBJ_HANDLER_P(expr, get_class_name)(Z_OBJ_P(expr) TSRMLS_CC);
ZEND_PUTS_EX(class_name->val);
} else {
ZEND_PUTS_EX("Unknown Class");
}
ZEND_PUTS_EX(" Object\n");
if (class_name) {
zend_string_release(class_name);
}
ZEND_PUTS_EX(" Object\n");
if ((properties = Z_OBJDEBUG_P(expr, is_temp)) == NULL) {
break;
}

View file

@ -196,21 +196,6 @@ ZEND_API char *zend_zval_type_name(const zval *arg) /* {{{ */
}
/* }}} */
/* returns 1 if you need to copy result, 0 if it's already a copy */
ZEND_API zend_string *zend_get_object_classname(const zend_object *object TSRMLS_DC) /* {{{ */
{
zend_string *ret;
if (object->handlers->get_class_name != NULL) {
ret = object->handlers->get_class_name(object, 0 TSRMLS_CC);
if (ret) {
return ret;
}
}
return object->ce->name;
}
/* }}} */
static int parse_arg_object_to_string(zval *arg, char **p, size_t *pl, int type TSRMLS_DC) /* {{{ */
{
if (Z_OBJ_HANDLER_P(arg, cast_object)) {
@ -3814,8 +3799,7 @@ ZEND_API void zend_update_property(zend_class_entry *scope, zval *object, const
EG(scope) = scope;
if (!Z_OBJ_HT_P(object)->write_property) {
zend_string *class_name = zend_get_object_classname(Z_OBJ_P(object) TSRMLS_CC);
zend_error(E_CORE_ERROR, "Property %s of class %s cannot be updated", name, class_name->val);
zend_error(E_CORE_ERROR, "Property %s of class %s cannot be updated", name, Z_OBJCE_P(object)->name->val);
}
ZVAL_STRINGL(&property, name, name_length);
Z_OBJ_HT_P(object)->write_property(object, &property, value, NULL TSRMLS_CC);
@ -3994,8 +3978,7 @@ ZEND_API zval *zend_read_property(zend_class_entry *scope, zval *object, const c
EG(scope) = scope;
if (!Z_OBJ_HT_P(object)->read_property) {
zend_string *class_name = zend_get_object_classname(Z_OBJ_P(object) TSRMLS_CC);
zend_error(E_CORE_ERROR, "Property %s of class %s cannot be read", name, class_name->val);
zend_error(E_CORE_ERROR, "Property %s of class %s cannot be read", name, Z_OBJCE_P(object)->name->val);
}
ZVAL_STRINGL(&property, name, name_length);

View file

@ -339,7 +339,6 @@ ZEND_API zval *zend_read_property(zend_class_entry *scope, zval *object, const c
ZEND_API zval *zend_read_static_property(zend_class_entry *scope, const char *name, int name_length, zend_bool silent TSRMLS_DC);
ZEND_API zend_string *zend_get_object_classname(const zend_object *object TSRMLS_DC);
ZEND_API char *zend_get_type_by_const(int type);
#define getThis() (Z_OBJ(EX(This)) ? &EX(This) : NULL)

View file

@ -811,7 +811,7 @@ ZEND_FUNCTION(get_class)
}
}
RETURN_STR(zend_get_object_classname(Z_OBJ_P(obj) TSRMLS_CC));
RETURN_STR(zend_string_copy(Z_OBJCE_P(obj)->name));
}
/* }}} */
@ -838,7 +838,6 @@ ZEND_FUNCTION(get_parent_class)
{
zval *arg;
zend_class_entry *ce = NULL;
zend_string *name;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|z", &arg) == FAILURE) {
return;
@ -854,12 +853,7 @@ ZEND_FUNCTION(get_parent_class)
}
if (Z_TYPE_P(arg) == IS_OBJECT) {
if (Z_OBJ_HT_P(arg)->get_class_name
&& (name = Z_OBJ_HT_P(arg)->get_class_name(Z_OBJ_P(arg), 1 TSRMLS_CC)) != NULL) {
RETURN_STR(name);
} else {
ce = Z_OBJ_P(arg)->ce;
}
} else if (Z_TYPE_P(arg) == IS_STRING) {
ce = zend_lookup_class(Z_STR_P(arg) TSRMLS_CC);
}
@ -2194,7 +2188,7 @@ ZEND_FUNCTION(debug_print_backtrace)
if (func->common.scope) {
class_name = func->common.scope->name;
} else {
class_name = zend_get_object_classname(object TSRMLS_CC);
class_name = object->ce->name;
}
call_type = "->";
@ -2301,7 +2295,6 @@ ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int
zend_function *func;
const char *function_name;
const char *filename;
zend_string *class_name;
const char *include_filename = NULL;
zval stack_frame;
@ -2416,8 +2409,7 @@ ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int
if (func->common.scope) {
add_assoc_str_ex(&stack_frame, "class", sizeof("class")-1, zend_string_copy(func->common.scope->name));
} else {
class_name = zend_get_object_classname(object TSRMLS_CC);
add_assoc_str_ex(&stack_frame, "class", sizeof("class")-1, zend_string_copy(class_name));
add_assoc_str_ex(&stack_frame, "class", sizeof("class")-1, zend_string_copy(object->ce->name));
}
if ((options & DEBUG_BACKTRACE_PROVIDE_OBJECT) != 0) {

View file

@ -89,11 +89,8 @@ ZEND_API void zend_throw_exception_internal(zval *exception TSRMLS_DC) /* {{{ */
{
#ifdef HAVE_DTRACE
if (DTRACE_EXCEPTION_THROWN_ENABLED()) {
zend_string *classname;
if (exception != NULL) {
classname = zend_get_object_classname(Z_OBJ_P(exception) TSRMLS_CC);
DTRACE_EXCEPTION_THROWN(classname->val);
DTRACE_EXCEPTION_THROWN(Z_OBJ_P(exception)->ce->val);
} else {
DTRACE_EXCEPTION_THROWN(NULL);
}
@ -452,7 +449,7 @@ static void _build_trace_args(zval *arg, smart_str *str TSRMLS_DC) /* {{{ */
break;
case IS_OBJECT:
smart_str_appends(str, "Object(");
smart_str_append(str, zend_get_object_classname(Z_OBJ_P(arg) TSRMLS_CC));
smart_str_append(str, Z_OBJCE_P(arg)->name);
smart_str_appends(str, "), ");
break;
}

View file

@ -1525,20 +1525,9 @@ exit:
}
/* }}} */
zend_string* zend_std_object_get_class_name(const zend_object *zobj, int parent TSRMLS_DC) /* {{{ */
zend_string *zend_std_object_get_class_name(const zend_object *zobj TSRMLS_DC) /* {{{ */
{
zend_class_entry *ce;
if (parent) {
if (!zobj->ce->parent) {
return NULL;
}
ce = zobj->ce->parent;
} else {
ce = zobj->ce;
}
return zend_string_copy(ce->name);
return zend_string_copy(zobj->ce->name);
}
/* }}} */

View file

@ -95,7 +95,10 @@ typedef void (*zend_object_dtor_obj_t)(zend_object *object TSRMLS_DC);
typedef void (*zend_object_free_obj_t)(zend_object *object TSRMLS_DC);
typedef zend_object* (*zend_object_clone_obj_t)(zval *object TSRMLS_DC);
typedef zend_string *(*zend_object_get_class_name_t)(const zend_object *object, int parent TSRMLS_DC);
/* Get class name for display in var_dump and other debugging functions.
* Must be defined and must return a non-NULL value. */
typedef zend_string *(*zend_object_get_class_name_t)(const zend_object *object TSRMLS_DC);
typedef int (*zend_object_compare_t)(zval *object1, zval *object2 TSRMLS_DC);
typedef int (*zend_object_compare_zvals_t)(zval *resul, zval *op1, zval *op2 TSRMLS_DC);

View file

@ -423,7 +423,7 @@ static union _zend_function *com_constructor_get(zend_object *object TSRMLS_DC)
}
}
static zend_string* com_class_name_get(const zend_object *object, int parent TSRMLS_DC)
static zend_string* com_class_name_get(const zend_object *object TSRMLS_DC)
{
php_com_dotnet_object *obj = (php_com_dotnet_object *)object;

View file

@ -333,7 +333,7 @@ static union _zend_function *saproxy_constructor_get(zend_object *object TSRMLS_
return NULL;
}
static zend_string* saproxy_class_name_get(const zend_object *object, int parent TSRMLS_DC)
static zend_string* saproxy_class_name_get(const zend_object *object TSRMLS_DC)
{
return zend_string_copy(php_com_saproxy_class_entry->name);
}

View file

@ -2636,14 +2636,10 @@ static union _zend_function *row_get_ctor(zend_object *object TSRMLS_DC)
return (union _zend_function*)&ctor;
}
static zend_string *row_get_classname(const zend_object *object, int parent TSRMLS_DC)
static zend_string *row_get_classname(const zend_object *object TSRMLS_DC)
{
if (parent) {
return NULL;
} else {
return zend_string_init("PDORow", sizeof("PDORow") - 1, 0);
}
}
static int row_compare(zval *object1, zval *object2 TSRMLS_DC)
{

View file

@ -35,7 +35,7 @@
} \
incomplete_class = 1; \
} else { \
class_name = zend_get_object_classname(Z_OBJ_P(struc) TSRMLS_CC); \
class_name = zend_string_copy(Z_OBJCE_P(struc)->name); \
}
#define PHP_CLEANUP_CLASS_ATTRIBUTES() \

View file

@ -163,13 +163,10 @@ again:
return;
}
if (Z_OBJ_HANDLER_P(struc, get_class_name)) {
class_name = Z_OBJ_HANDLER_P(struc, get_class_name)(Z_OBJ_P(struc), 0 TSRMLS_CC);
class_name = Z_OBJ_HANDLER_P(struc, get_class_name)(Z_OBJ_P(struc) TSRMLS_CC);
php_printf("%sobject(%s)#%d (%d) {\n", COMMON, class_name->val, Z_OBJ_HANDLE_P(struc), myht ? zend_obj_num_elements(myht) : 0);
zend_string_release(class_name);
} else {
php_printf("%sobject(unknown class)#%d (%d) {\n", COMMON, Z_OBJ_HANDLE_P(struc), myht ? zend_obj_num_elements(myht) : 0);
}
if (myht) {
zend_ulong num;
zend_string *key;
@ -334,7 +331,7 @@ again:
myht->u.v.nApplyCount++;
}
}
class_name = Z_OBJ_HANDLER_P(struc, get_class_name)(Z_OBJ_P(struc), 0 TSRMLS_CC);
class_name = Z_OBJ_HANDLER_P(struc, get_class_name)(Z_OBJ_P(struc) TSRMLS_CC);
php_printf("%sobject(%s)#%d (%d) refcount(%u){\n", COMMON, class_name->val, Z_OBJ_HANDLE_P(struc), myht ? zend_obj_num_elements(myht) : 0, Z_REFCOUNT_P(struc));
zend_string_release(class_name);
if (myht) {
@ -456,7 +453,6 @@ PHPAPI void php_var_export_ex(zval *struc, int level, smart_str *buf TSRMLS_DC)
HashTable *myht;
char *tmp_str;
size_t tmp_len;
zend_string *class_name;
zend_string *ztmp, *ztmp2;
zend_ulong index;
zend_string *key;
@ -533,12 +529,10 @@ again:
smart_str_appendc(buf, '\n');
buffer_append_spaces(buf, level - 1);
}
class_name = Z_OBJ_HANDLER_P(struc, get_class_name)(Z_OBJ_P(struc), 0 TSRMLS_CC);
smart_str_append(buf, class_name);
smart_str_append(buf, Z_OBJCE_P(struc)->name);
smart_str_appendl(buf, "::__set_state(array(\n", 21);
zend_string_release(class_name);
if (myht) {
ZEND_HASH_FOREACH_KEY_VAL_IND(myht, index, key, val) {
php_object_element_export(val, index, key, level, buf TSRMLS_CC);