]> granicus.if.org Git - php/commitdiff
Closure::fromCallable(): Better LSB handling
authorNikita Popov <nikic@php.net>
Tue, 5 Jul 2016 13:43:27 +0000 (15:43 +0200)
committerNikita Popov <nikic@php.net>
Tue, 5 Jul 2016 13:44:17 +0000 (15:44 +0200)
The previous fix missed the "late" part of "late static binding" :)

Zend/tests/closures/closure_from_callable_lsb.phpt
Zend/zend_closures.c

index bd57fba72ed1fb5b856b576fa214fb48b0094b6b..950985bdadbcfed1e457fa522fedb00e81174eb5 100644 (file)
@@ -3,14 +3,19 @@ Testing Closure::fromCallable() functionality: Late static binding
 --FILE--
 <?php
 
-class Foo {
-    const BAR = 1;
-    public static function method() {
-        return static::BAR;
+class A {
+    public static function test() {
+        var_dump(static::class);
     }
 }
-var_dump(Closure::fromCallable(['Foo', 'method'])());
+
+class B extends A {
+}
+
+Closure::fromCallable(['A', 'test'])();
+Closure::fromCallable(['B', 'test'])();
 
 ?>
 --EXPECT--
-int(1)
+string(1) "A"
+string(1) "B"
index ef321e7cbf9fa2e5293573f1bb08b7bca7d8562d..137e437fb945f9d6e255965f07633416d566d30c 100644 (file)
@@ -238,6 +238,7 @@ ZEND_METHOD(Closure, bind)
 static void zend_closure_call_magic(INTERNAL_FUNCTION_PARAMETERS) /* {{{ */ {
        zend_fcall_info fci;
        zend_fcall_info_cache fcc;
+       zval params[2];
 
        memset(&fci, 0, sizeof(zend_fcall_info));
        memset(&fci, 0, sizeof(zend_fcall_info_cache));
@@ -247,7 +248,7 @@ static void zend_closure_call_magic(INTERNAL_FUNCTION_PARAMETERS) /* {{{ */ {
 
        fcc.initialized = 1;
        fcc.function_handler = (zend_function *) EX(func)->common.arg_info;
-       fci.params = (zval*) emalloc(sizeof(zval) * 2);
+       fci.params = params;
        fci.param_count = 2;
        ZVAL_STR(&fci.params[0], EX(func)->common.function_name);
        array_init(&fci.params[1]);
@@ -261,7 +262,6 @@ static void zend_closure_call_magic(INTERNAL_FUNCTION_PARAMETERS) /* {{{ */ {
 
        zval_ptr_dtor(&fci.params[0]);
        zval_ptr_dtor(&fci.params[1]);
-       efree(fci.params);
 }
 /* }}} */
 
@@ -276,10 +276,6 @@ static int zend_create_closure_from_callable(zval *return_value, zval *callable,
        }
 
        mptr = fcc.function_handler;
-       if (mptr == NULL) {
-               return FAILURE;
-       }
-
        if (mptr->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) {
                memset(&call, 0, sizeof(zend_internal_function));
 
@@ -295,9 +291,9 @@ static int zend_create_closure_from_callable(zval *return_value, zval *callable,
 
        if (fcc.object) {
                ZVAL_OBJ(&instance, fcc.object);
-               zend_create_fake_closure(return_value, mptr, mptr->common.scope, fcc.object->ce, &instance);
+               zend_create_fake_closure(return_value, mptr, mptr->common.scope, fcc.called_scope, &instance);
        } else {
-               zend_create_fake_closure(return_value, mptr, mptr->common.scope, mptr->common.scope, NULL);
+               zend_create_fake_closure(return_value, mptr, mptr->common.scope, fcc.called_scope, NULL);
        }
 
        return SUCCESS;