From: Stanislav Malyshev Date: Mon, 19 May 2003 17:12:56 +0000 (+0000) Subject: fix __clone X-Git-Tag: RELEASE_1_0_2~735 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=462eff349767fb2a60b79c288910be56a674f357;p=php fix __clone --- diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 5bdffcbacd..9d1db6ec52 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -1215,7 +1215,10 @@ void zend_do_begin_method_call(znode *left_bracket TSRMLS_DC) if ((last_op->op2.op_type == IS_CONST) && (last_op->op2.u.constant.value.str.len == sizeof(ZEND_CLONE_FUNC_NAME)-1) && !memcmp(last_op->op2.u.constant.value.str.val, ZEND_CLONE_FUNC_NAME, sizeof(ZEND_CLONE_FUNC_NAME))) { last_op->opcode = ZEND_CLONE; - left_bracket->u.constant.value.lval = ZEND_CLONE; + left_bracket->op_type = IS_UNUSED; + zval_dtor(&last_op->op2.u.constant); + SET_UNUSED(last_op->op2); + left_bracket->u.constant.value.lval = get_next_op_number(CG(active_op_array))-1; zend_stack_push(&CG(function_call_stack), (void *) &ptr, sizeof(zend_function *)); zend_do_extended_fcall_begin(TSRMLS_C); return; @@ -1328,14 +1331,22 @@ void zend_do_end_function_call(znode *function_name, znode *result, znode *argum { zend_op *opline; - opline = get_next_op(CG(active_op_array) TSRMLS_CC); - - if (!is_method && !is_dynamic_fcall && function_name->op_type==IS_CONST) { - opline->opcode = ZEND_DO_FCALL; - opline->op1 = *function_name; + + if(is_method && function_name && function_name->op_type == IS_UNUSED) { + /* clone */ + if(argument_list->u.constant.value.lval != 0) { + zend_error(E_WARNING, "Clone method does not require arguments"); + } + opline = &CG(active_op_array)->opcodes[function_name->u.constant.value.lval]; } else { - opline->opcode = ZEND_DO_FCALL_BY_NAME; - SET_UNUSED(opline->op1); + opline = get_next_op(CG(active_op_array) TSRMLS_CC); + if (!is_method && !is_dynamic_fcall && function_name->op_type==IS_CONST) { + opline->opcode = ZEND_DO_FCALL; + opline->op1 = *function_name; + } else { + opline->opcode = ZEND_DO_FCALL_BY_NAME; + SET_UNUSED(opline->op1); + } } opline->result.u.var = get_temporary_variable(CG(active_op_array)); diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index bed9bd8a97..5c00d7f8df 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -3172,6 +3172,12 @@ int zend_clone_handler(ZEND_OPCODE_HANDLER_ARGS) { zval *obj = get_zval_ptr(&EX(opline)->op1, EX(Ts), &EG(free_op1), BP_VAR_R); + if(Z_TYPE_P(obj) != IS_OBJECT) { + zend_error(E_WARNING, "__clone method called on non-object"); + EX_T(EX(opline)->result.u.var).var.ptr = EG(error_zval_ptr); + EX_T(EX(opline)->result.u.var).var.ptr->refcount++; + NEXT_OPCODE(); + } EX_T(EX(opline)->result.u.var).var.ptr_ptr = &EX_T(EX(opline)->result.u.var).var.ptr; ALLOC_ZVAL(EX_T(EX(opline)->result.u.var).var.ptr); EX_T(EX(opline)->result.u.var).var.ptr->value.obj = Z_OBJ_HT_P(obj)->clone_obj(obj TSRMLS_CC);