diff options
Diffstat (limited to 'Zend/zend_closures.c')
| -rw-r--r-- | Zend/zend_closures.c | 9 |
1 files changed, 8 insertions, 1 deletions
diff --git a/Zend/zend_closures.c b/Zend/zend_closures.c index b035a4f54a..a394c91c60 100644 --- a/Zend/zend_closures.c +++ b/Zend/zend_closures.c @@ -564,7 +564,14 @@ ZEND_API void zend_create_closure(zval *res, zend_function *func, zend_class_ent closure->func.common.prototype = (zend_function*)closure; closure->func.common.fn_flags |= ZEND_ACC_CLOSURE; /* wrap internal function handler to avoid memory leak */ - closure->orig_internal_handler = closure->func.internal_function.handler; + if (UNEXPECTED(closure->func.internal_function.handler == zend_closure_internal_handler)) { + /* avoid infinity recursion, by taking handler from nested closure */ + zend_closure *nested = (zend_closure*)((char*)func - XtOffsetOf(zend_closure, func)); + ZEND_ASSERT(nested->std.ce == zend_ce_closure); + closure->orig_internal_handler = nested->orig_internal_handler; + } else { + closure->orig_internal_handler = closure->func.internal_function.handler; + } closure->func.internal_function.handler = zend_closure_internal_handler; /* verify that we aren't binding internal function to a wrong scope */ if(func->common.scope != NULL) { |
