From b96318105b8a908ec3cb294b8133e36d1b8cba7a Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Fri, 21 Feb 2014 22:34:30 +0800 Subject: [PATCH] Use zend_string for arg_info to fixed segfault in Zend/tests/argument_restriction_003.phpt --- Zend/zend_compile.c | 56 +++++++++++++++------------------------------ Zend/zend_compile.h | 8 +++---- Zend/zend_execute.c | 3 +-- Zend/zend_opcode.c | 2 +- 4 files changed, 25 insertions(+), 44 deletions(-) diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index fb361e53e0..d3e98b6c95 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -1906,7 +1906,6 @@ void zend_do_receive_param(zend_uchar op, znode *varname, const znode *initializ cur_arg_info->allow_null = 1; cur_arg_info->is_variadic = is_variadic; cur_arg_info->class_name = NULL; - cur_arg_info->class_name_len = 0; if (class_type->op_type != IS_UNUSED) { cur_arg_info->allow_null = 0; @@ -1936,8 +1935,7 @@ void zend_do_receive_param(zend_uchar op, znode *varname, const znode *initializ zend_resolve_class_name(class_type TSRMLS_CC); } Z_STR(class_type->u.constant) = zend_new_interned_string(Z_STR(class_type->u.constant) TSRMLS_CC); - cur_arg_info->class_name = Z_STRVAL(class_type->u.constant); - cur_arg_info->class_name_len = Z_STRLEN(class_type->u.constant); + cur_arg_info->class_name = STR_COPY(Z_STR(class_type->u.constant)); if (op == ZEND_RECV_INIT) { if (Z_TYPE(initialization->u.constant) == IS_NULL || (Z_TYPE(initialization->u.constant) == IS_CONSTANT && !strcasecmp(Z_STRVAL(initialization->u.constant), "NULL")) || Z_TYPE(initialization->u.constant) == IS_CONSTANT_AST) { cur_arg_info->allow_null = 1; @@ -3283,32 +3281,20 @@ static zend_bool zend_do_perform_implementation_check(const zend_function *fe, c if (fe_arg_info->class_name) { zend_string *fe_class_name, *proto_class_name; - if (!strcasecmp(fe_arg_info->class_name, "parent") && proto->common.scope) { - fe_class_name = STR_INIT( - proto->common.scope->name->val, - proto->common.scope->name->len, 0); - } else if (!strcasecmp(fe_arg_info->class_name, "self") && fe->common.scope) { - fe_class_name = STR_INIT( - fe->common.scope->name->val, - fe->common.scope->name->len, 0); + if (!strcasecmp(fe_arg_info->class_name->val, "parent") && proto->common.scope) { + fe_class_name = proto->common.scope->name; + } else if (!strcasecmp(fe_arg_info->class_name->val, "self") && fe->common.scope) { + fe_class_name = fe->common.scope->name; } else { - fe_class_name = STR_INIT( - fe_arg_info->class_name, - fe_arg_info->class_name_len, 0); + fe_class_name = fe_arg_info->class_name; } - if (!strcasecmp(proto_arg_info->class_name, "parent") && proto->common.scope && proto->common.scope->parent) { - proto_class_name = STR_INIT( - proto->common.scope->parent->name->val, - proto->common.scope->parent->name->len, 0); - } else if (!strcasecmp(proto_arg_info->class_name, "self") && proto->common.scope) { - proto_class_name = STR_INIT( - proto->common.scope->name->val, - proto->common.scope->name->len, 0); + if (!strcasecmp(proto_arg_info->class_name->val, "parent") && proto->common.scope && proto->common.scope->parent) { + proto_class_name = proto->common.scope->parent->name; + } else if (!strcasecmp(proto_arg_info->class_name->val, "self") && proto->common.scope) { + proto_class_name = proto->common.scope->name; } else { - proto_class_name = STR_INIT( - proto_arg_info->class_name, - proto_arg_info->class_name_len, 0); + proto_class_name = proto_arg_info->class_name; } if (strcasecmp(fe_class_name->val, proto_class_name->val)!=0) { @@ -3388,21 +3374,17 @@ static char * zend_get_function_declaration(zend_function *fptr TSRMLS_DC) /* {{ required = fptr->common.required_num_args; for (i = 0; i < fptr->common.num_args;) { if (arg_info->class_name) { - const char *class_name; - zend_uint class_name_len; - if (!strcasecmp(arg_info->class_name, "self") && fptr->common.scope ) { - class_name = fptr->common.scope->name->val; - class_name_len = fptr->common.scope->name->len; - } else if (!strcasecmp(arg_info->class_name, "parent") && fptr->common.scope->parent) { - class_name = fptr->common.scope->parent->name->val; - class_name_len = fptr->common.scope->parent->name->len; + zend_string *class_name; + if (!strcasecmp(arg_info->class_name->val, "self") && fptr->common.scope ) { + class_name = fptr->common.scope->name; + } else if (!strcasecmp(arg_info->class_name->val, "parent") && fptr->common.scope->parent) { + class_name = fptr->common.scope->parent->name; } else { class_name = arg_info->class_name; - class_name_len = arg_info->class_name_len; } - REALLOC_BUF_IF_EXCEED(buf, offset, length, class_name_len); - memcpy(offset, class_name, class_name_len); - offset += class_name_len; + REALLOC_BUF_IF_EXCEED(buf, offset, length, class_name->len); + memcpy(offset, class_name->val, class_name->len); + offset += class_name->len; *(offset++) = ' '; } else if (arg_info->type_hint) { zend_uint type_name_len; diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index 050cc47993..990a34c67c 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -228,10 +228,10 @@ typedef struct _zend_property_info { typedef struct _zend_arg_info { const char *name; zend_uint name_len; - const char *class_name; - zend_uint class_name_len; -//??? zend_string *name; -//??? zend_string *class_name; +//??? const char *class_name; +// zend_uint class_name_len; +// zend_string *name; + zend_string *class_name; zend_uchar type_hint; zend_uchar pass_by_reference; zend_bool allow_null; diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 21efb7fdd2..c1fe7ce49f 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -642,9 +642,8 @@ static inline void make_real_object(zval *object_ptr TSRMLS_DC) ZEND_API char * zend_verify_arg_class_kind(const zend_arg_info *cur_arg_info, ulong fetch_type, char **class_name, zend_class_entry **pce TSRMLS_DC) { - zend_string *key = STR_INIT(cur_arg_info->class_name, cur_arg_info->class_name_len, 0); + zend_string *key = cur_arg_info->class_name; *pce = zend_fetch_class(key, (fetch_type | ZEND_FETCH_CLASS_AUTO | ZEND_FETCH_CLASS_NO_AUTOLOAD) TSRMLS_CC); - STR_FREE(key); *class_name = (*pce) ? (*pce)->name->val : (char*)cur_arg_info->class_name; if (*pce && (*pce)->ce_flags & ZEND_ACC_INTERFACE) { return "implement interface "; diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c index 4e25200e4a..98deca6206 100644 --- a/Zend/zend_opcode.c +++ b/Zend/zend_opcode.c @@ -412,7 +412,7 @@ ZEND_API void destroy_op_array(zend_op_array *op_array TSRMLS_DC) efree((char*)op_array->arg_info[i].name); if (op_array->arg_info[i].class_name) { //??? str_efree(op_array->arg_info[i].class_name); - efree((char*)op_array->arg_info[i].class_name); + STR_RELEASE(op_array->arg_info[i].class_name); } } efree(op_array->arg_info); -- 2.40.0