diff options
| -rw-r--r-- | Zend/zend_compile.c | 15 | ||||
| -rw-r--r-- | Zend/zend_compile.h | 4 | ||||
| -rw-r--r-- | Zend/zend_execute.c | 11 | 
3 files changed, 18 insertions, 12 deletions
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 8cdf8cb93a..54871f8251 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -961,6 +961,11 @@ void do_fetch_class(znode *result, znode *class_entry, znode *class_name TSRMLS_  		SET_UNUSED(opline->op2);  		opline->extended_value = ZEND_FETCH_CLASS_SELF;  		zval_dtor(&class_name->u.constant); +	} else if ((class_name->u.constant.value.str.len == (sizeof("parent") - 1)) && +		!memcmp(class_name->u.constant.value.str.val, "parent", sizeof("parent"))) { +		SET_UNUSED(opline->op2); +		opline->extended_value = ZEND_FETCH_CLASS_PARENT; +		zval_dtor(&class_name->u.constant);  	} else if ((class_name->u.constant.value.str.len == (sizeof("main") - 1)) &&  		!memcmp(class_name->u.constant.value.str.val, "main", sizeof("main"))) {  		SET_UNUSED(opline->op2); @@ -999,16 +1004,6 @@ void zend_do_begin_class_member_function_call(znode *class_name, znode *function  	zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);  	opline->opcode = ZEND_INIT_FCALL_BY_NAME; -	zend_str_tolower(class_name->u.constant.value.str.val, class_name->u.constant.value.str.len); -	if ((class_name->u.constant.value.str.len == sizeof("parent")-1) -		&& !memcmp(class_name->u.constant.value.str.val, "parent", sizeof("parent")-1)) { -		if (!CG(active_ce_parent_class_name).value.str.val) { -			zend_error(E_COMPILE_ERROR, "No parent class available"); -		} -		efree(class_name->u.constant.value.str.val); -		class_name->u.constant.value.str.len = CG(active_ce_parent_class_name).value.str.len; -		class_name->u.constant.value.str.val = estrndup(CG(active_ce_parent_class_name).value.str.val, class_name->u.constant.value.str.len); -	}  	opline->op1 = *class_name;  	opline->op2 = *function_name;  	opline->extended_value = ZEND_MEMBER_FUNC_CALL; diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index 6813fa6dd8..739afcd898 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -558,7 +558,9 @@ int zendlex(znode *zendlval TSRMLS_DC);  /* class fetches */  #define ZEND_FETCH_CLASS_DEFAULT	0  #define ZEND_FETCH_CLASS_SELF		1 -#define ZEND_FETCH_CLASS_MAIN		2 +#define ZEND_FETCH_CLASS_PARENT		2 +#define ZEND_FETCH_CLASS_MAIN		3 +  /* variable parsing type (compile-time) */  #define ZEND_PARSED_MEMBER			(1<<0) diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index cf9c4b42e4..70196d7dd4 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -1503,7 +1503,16 @@ binary_assign_op_addr: {  						} else if (EX(opline)->extended_value == ZEND_FETCH_CLASS_MAIN) {  							EX(Ts)[EX(opline)->result.u.var].EA.class_entry = EG(main_class_ptr);  							NEXT_OPCODE(); -						} +						} else if (EX(opline)->extended_value == ZEND_FETCH_CLASS_PARENT) { +							if (!EG(namespace)) { +								zend_error(E_ERROR, "Cannot fetch parent:: when no class scope is active"); +							} +							if (!EG(namespace)->parent) { +								zend_error(E_ERROR, "Cannot fetch parent:: as current class scope has no parent"); +							} +							EX(Ts)[EX(opline)->result.u.var].EA.class_entry = EG(namespace)->parent; +							NEXT_OPCODE(); +						}   						class_name = get_zval_ptr(&EX(opline)->op2, EX(Ts), &EG(free_op2), BP_VAR_R);  | 
