summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2018-09-13 13:36:09 +0300
committerDmitry Stogov <dmitry@zend.com>2018-09-13 13:36:09 +0300
commitbc288c47230919c326b82133ff5306f4eff690b4 (patch)
tree52f41a44d141cacb24baca746b1010ea81332948
parent72bf2def6b718ae9ca243b6a9ab9a3a85d255f96 (diff)
downloadphp-git-bc288c47230919c326b82133ff5306f4eff690b4.tar.gz
Simplify __clone() visibility check (magic methods still don't respect ZEND_ACC_CHANGED).
-rw-r--r--Zend/zend_execute.c4
-rw-r--r--Zend/zend_vm_def.h23
-rw-r--r--Zend/zend_vm_execute.h92
3 files changed, 34 insertions, 85 deletions
diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c
index fa2f17571d..6859654bbe 100644
--- a/Zend/zend_execute.c
+++ b/Zend/zend_execute.c
@@ -2287,6 +2287,10 @@ static zend_never_inline void zend_fetch_this_var(int type OPLINE_DC EXECUTE_DAT
}
}
+static zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_wrong_clone_call(zend_function *clone, zend_class_entry *scope)
+{
+ zend_throw_error(NULL, "Call to %s %s::__clone() from context '%s'", zend_visibility_string(clone->common.fn_flags), ZSTR_VAL(clone->common.scope->name), scope ? ZSTR_VAL(scope->name) : "");
+}
#if ZEND_INTENSIVE_DEBUGGING
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index e51589a40a..0b7ebf8f89 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -5029,23 +5029,12 @@ ZEND_VM_COLD_CONST_HANDLER(110, ZEND_CLONE, CONST|TMPVAR|UNUSED|THIS|CV, ANY)
HANDLE_EXCEPTION();
}
- if (clone) {
- if (clone->op_array.fn_flags & ZEND_ACC_PRIVATE) {
- /* Ensure that if we're calling a private function, we're allowed to do so.
- */
- scope = EX(func)->op_array.scope;
- if (!zend_check_private(clone, scope, clone->common.function_name)) {
- zend_throw_error(NULL, "Call to private %s::__clone() from context '%s'", ZSTR_VAL(clone->common.scope->name), scope ? ZSTR_VAL(scope->name) : "");
- FREE_OP1();
- ZVAL_UNDEF(EX_VAR(opline->result.var));
- HANDLE_EXCEPTION();
- }
- } else if ((clone->common.fn_flags & ZEND_ACC_PROTECTED)) {
- /* Ensure that if we're calling a protected function, we're allowed to do so.
- */
- scope = EX(func)->op_array.scope;
- if (UNEXPECTED(!zend_check_protected(zend_get_function_root_class(clone), scope))) {
- zend_throw_error(NULL, "Call to protected %s::__clone() from context '%s'", ZSTR_VAL(clone->common.scope->name), scope ? ZSTR_VAL(scope->name) : "");
+ if (clone && !(clone->common.fn_flags & ZEND_ACC_PUBLIC)) {
+ scope = EX(func)->op_array.scope;
+ if (clone->common.scope != scope) {
+ if (UNEXPECTED(clone->common.fn_flags & ZEND_ACC_PRIVATE)
+ || UNEXPECTED(!zend_check_protected(zend_get_function_root_class(clone), scope))) {
+ zend_wrong_clone_call(clone, scope);
FREE_OP1();
ZVAL_UNDEF(EX_VAR(opline->result.var));
HANDLE_EXCEPTION();
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index d3a937de97..ecde1bcddc 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -3048,23 +3048,12 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_CONST_
HANDLE_EXCEPTION();
}
- if (clone) {
- if (clone->op_array.fn_flags & ZEND_ACC_PRIVATE) {
- /* Ensure that if we're calling a private function, we're allowed to do so.
- */
- scope = EX(func)->op_array.scope;
- if (!zend_check_private(clone, scope, clone->common.function_name)) {
- zend_throw_error(NULL, "Call to private %s::__clone() from context '%s'", ZSTR_VAL(clone->common.scope->name), scope ? ZSTR_VAL(scope->name) : "");
-
- ZVAL_UNDEF(EX_VAR(opline->result.var));
- HANDLE_EXCEPTION();
- }
- } else if ((clone->common.fn_flags & ZEND_ACC_PROTECTED)) {
- /* Ensure that if we're calling a protected function, we're allowed to do so.
- */
- scope = EX(func)->op_array.scope;
- if (UNEXPECTED(!zend_check_protected(zend_get_function_root_class(clone), scope))) {
- zend_throw_error(NULL, "Call to protected %s::__clone() from context '%s'", ZSTR_VAL(clone->common.scope->name), scope ? ZSTR_VAL(scope->name) : "");
+ if (clone && !(clone->common.fn_flags & ZEND_ACC_PUBLIC)) {
+ scope = EX(func)->op_array.scope;
+ if (clone->common.scope != scope) {
+ if (UNEXPECTED(clone->common.fn_flags & ZEND_ACC_PRIVATE)
+ || UNEXPECTED(!zend_check_protected(zend_get_function_root_class(clone), scope))) {
+ zend_wrong_clone_call(clone, scope);
ZVAL_UNDEF(EX_VAR(opline->result.var));
HANDLE_EXCEPTION();
@@ -12588,23 +12577,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_TMPVAR_HANDLER(ZEND
HANDLE_EXCEPTION();
}
- if (clone) {
- if (clone->op_array.fn_flags & ZEND_ACC_PRIVATE) {
- /* Ensure that if we're calling a private function, we're allowed to do so.
- */
- scope = EX(func)->op_array.scope;
- if (!zend_check_private(clone, scope, clone->common.function_name)) {
- zend_throw_error(NULL, "Call to private %s::__clone() from context '%s'", ZSTR_VAL(clone->common.scope->name), scope ? ZSTR_VAL(scope->name) : "");
- zval_ptr_dtor_nogc(free_op1);
- ZVAL_UNDEF(EX_VAR(opline->result.var));
- HANDLE_EXCEPTION();
- }
- } else if ((clone->common.fn_flags & ZEND_ACC_PROTECTED)) {
- /* Ensure that if we're calling a protected function, we're allowed to do so.
- */
- scope = EX(func)->op_array.scope;
- if (UNEXPECTED(!zend_check_protected(zend_get_function_root_class(clone), scope))) {
- zend_throw_error(NULL, "Call to protected %s::__clone() from context '%s'", ZSTR_VAL(clone->common.scope->name), scope ? ZSTR_VAL(scope->name) : "");
+ if (clone && !(clone->common.fn_flags & ZEND_ACC_PUBLIC)) {
+ scope = EX(func)->op_array.scope;
+ if (clone->common.scope != scope) {
+ if (UNEXPECTED(clone->common.fn_flags & ZEND_ACC_PRIVATE)
+ || UNEXPECTED(!zend_check_protected(zend_get_function_root_class(clone), scope))) {
+ zend_wrong_clone_call(clone, scope);
zval_ptr_dtor_nogc(free_op1);
ZVAL_UNDEF(EX_VAR(opline->result.var));
HANDLE_EXCEPTION();
@@ -30665,23 +30643,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_UNUSED_HANDLER(ZEND
HANDLE_EXCEPTION();
}
- if (clone) {
- if (clone->op_array.fn_flags & ZEND_ACC_PRIVATE) {
- /* Ensure that if we're calling a private function, we're allowed to do so.
- */
- scope = EX(func)->op_array.scope;
- if (!zend_check_private(clone, scope, clone->common.function_name)) {
- zend_throw_error(NULL, "Call to private %s::__clone() from context '%s'", ZSTR_VAL(clone->common.scope->name), scope ? ZSTR_VAL(scope->name) : "");
-
- ZVAL_UNDEF(EX_VAR(opline->result.var));
- HANDLE_EXCEPTION();
- }
- } else if ((clone->common.fn_flags & ZEND_ACC_PROTECTED)) {
- /* Ensure that if we're calling a protected function, we're allowed to do so.
- */
- scope = EX(func)->op_array.scope;
- if (UNEXPECTED(!zend_check_protected(zend_get_function_root_class(clone), scope))) {
- zend_throw_error(NULL, "Call to protected %s::__clone() from context '%s'", ZSTR_VAL(clone->common.scope->name), scope ? ZSTR_VAL(scope->name) : "");
+ if (clone && !(clone->common.fn_flags & ZEND_ACC_PUBLIC)) {
+ scope = EX(func)->op_array.scope;
+ if (clone->common.scope != scope) {
+ if (UNEXPECTED(clone->common.fn_flags & ZEND_ACC_PRIVATE)
+ || UNEXPECTED(!zend_check_protected(zend_get_function_root_class(clone), scope))) {
+ zend_wrong_clone_call(clone, scope);
ZVAL_UNDEF(EX_VAR(opline->result.var));
HANDLE_EXCEPTION();
@@ -37428,23 +37395,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_CV_HANDLER(ZEND_OPC
HANDLE_EXCEPTION();
}
- if (clone) {
- if (clone->op_array.fn_flags & ZEND_ACC_PRIVATE) {
- /* Ensure that if we're calling a private function, we're allowed to do so.
- */
- scope = EX(func)->op_array.scope;
- if (!zend_check_private(clone, scope, clone->common.function_name)) {
- zend_throw_error(NULL, "Call to private %s::__clone() from context '%s'", ZSTR_VAL(clone->common.scope->name), scope ? ZSTR_VAL(scope->name) : "");
-
- ZVAL_UNDEF(EX_VAR(opline->result.var));
- HANDLE_EXCEPTION();
- }
- } else if ((clone->common.fn_flags & ZEND_ACC_PROTECTED)) {
- /* Ensure that if we're calling a protected function, we're allowed to do so.
- */
- scope = EX(func)->op_array.scope;
- if (UNEXPECTED(!zend_check_protected(zend_get_function_root_class(clone), scope))) {
- zend_throw_error(NULL, "Call to protected %s::__clone() from context '%s'", ZSTR_VAL(clone->common.scope->name), scope ? ZSTR_VAL(scope->name) : "");
+ if (clone && !(clone->common.fn_flags & ZEND_ACC_PUBLIC)) {
+ scope = EX(func)->op_array.scope;
+ if (clone->common.scope != scope) {
+ if (UNEXPECTED(clone->common.fn_flags & ZEND_ACC_PRIVATE)
+ || UNEXPECTED(!zend_check_protected(zend_get_function_root_class(clone), scope))) {
+ zend_wrong_clone_call(clone, scope);
ZVAL_UNDEF(EX_VAR(opline->result.var));
HANDLE_EXCEPTION();