diff options
| author | Nikita Popov <nikic@php.net> | 2016-03-29 23:48:07 +0200 |
|---|---|---|
| committer | Nikita Popov <nikic@php.net> | 2016-04-08 00:38:44 +0200 |
| commit | 75af8150f58fb55637ac12b33d469b27adef9d76 (patch) | |
| tree | 682e004586b35e5ecb368a6f29e082779d15cd42 /Zend/zend_closures.c | |
| parent | aed42496534fe54c5c0ce64fe0ca5c9d801d6161 (diff) | |
| download | php-git-75af8150f58fb55637ac12b33d469b27adef9d76.tar.gz | |
Forbid binding methods to incompatible $this
This prohibits binding closures returned by
ReflectionMethod::getClosure() to a $this, which is not an
instance of the method scope. This restriction was already in
place for internal methods, now it is extended to user methods.
ML discussion: http://markmail.org/message/zepnhdyr3kij6di6
Diffstat (limited to 'Zend/zend_closures.c')
| -rw-r--r-- | Zend/zend_closures.c | 7 |
1 files changed, 4 insertions, 3 deletions
diff --git a/Zend/zend_closures.c b/Zend/zend_closures.c index d52d0b5c25..fd0738f32f 100644 --- a/Zend/zend_closures.c +++ b/Zend/zend_closures.c @@ -77,16 +77,17 @@ static zend_bool zend_valid_closure_binding( zend_closure *closure, zval *newthis, zend_class_entry *scope) /* {{{ */ { zend_function *func = &closure->func; + zend_bool is_fake_closure = (func->common.fn_flags & ZEND_ACC_FAKE_CLOSURE) != 0; if (newthis) { if (func->common.fn_flags & ZEND_ACC_STATIC) { zend_error(E_WARNING, "Cannot bind an instance to a static closure"); return 0; } - if (func->type == ZEND_INTERNAL_FUNCTION && func->common.scope && + if (is_fake_closure && func->common.scope && !instanceof_function(Z_OBJCE_P(newthis), func->common.scope)) { /* Binding incompatible $this to an internal method is not supported. */ - zend_error(E_WARNING, "Cannot bind internal method %s::%s() to object of class %s", + zend_error(E_WARNING, "Cannot bind method %s::%s() to object of class %s", ZSTR_VAL(func->common.scope->name), ZSTR_VAL(func->common.function_name), ZSTR_VAL(Z_OBJCE_P(newthis)->name)); @@ -105,7 +106,7 @@ static zend_bool zend_valid_closure_binding( return 0; } - if ((func->common.fn_flags & ZEND_ACC_FAKE_CLOSURE) && scope != func->common.scope) { + if (is_fake_closure && scope != func->common.scope) { zend_error(E_WARNING, "Cannot rebind scope of closure created by ReflectionFunctionAbstract::getClosure()"); return 0; } |
