Skip to content

Commit 531413f

Browse files
committed
Merge branch 'PHP-8.0'
* PHP-8.0: Fix #81076 Invalid implicit binds cause incorrect count in static vars of closure debug info
2 parents 6408ebb + 213063f commit 531413f

File tree

3 files changed

+33
-7
lines changed

3 files changed

+33
-7
lines changed

NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ PHP NEWS
1111
the method is private). (Nikita)
1212
. Implemented FR #77372 (Relative file path is removed from uploaded file).
1313
(Björn Tantau)
14+
. Fixed bug #81076 (incorrect debug info on Closures with implicit binds).
15+
(krakjoe)
1416

1517
- Standard:
1618
. Fixed bug #77627 (method_exists on Closure::__invoke inconsistency).

Zend/tests/bug81076.phpt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
--TEST--
2+
Bug #81076 Invalid implicit binds cause incorrect static var count in closure debug info
3+
--FILE--
4+
<?php
5+
var_dump(fn() => [$why, $do, $we, $count]);
6+
?>
7+
--EXPECT--
8+
object(Closure)#1 (0) {
9+
}

Zend/zend_closures.c

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -515,16 +515,31 @@ static HashTable *zend_closure_get_debug_info(zend_object *object, int *is_temp)
515515

516516
if (closure->func.type == ZEND_USER_FUNCTION && closure->func.op_array.static_variables) {
517517
zval *var;
518-
HashTable *static_variables =
519-
ZEND_MAP_PTR_GET(closure->func.op_array.static_variables_ptr);
520-
ZVAL_ARR(&val, zend_array_dup(static_variables));
521-
zend_hash_update(debug_info, ZSTR_KNOWN(ZEND_STR_STATIC), &val);
522-
ZEND_HASH_FOREACH_VAL(Z_ARRVAL(val), var) {
518+
zend_string *key;
519+
HashTable *static_variables = ZEND_MAP_PTR_GET(closure->func.op_array.static_variables_ptr);
520+
521+
array_init(&val);
522+
523+
ZEND_HASH_FOREACH_STR_KEY_VAL(static_variables, key, var) {
524+
zval copy;
525+
523526
if (Z_TYPE_P(var) == IS_CONSTANT_AST) {
524-
zval_ptr_dtor(var);
525-
ZVAL_STRING(var, "<constant ast>");
527+
ZVAL_STRING(&copy, "<constant ast>");
528+
} else {
529+
if (Z_ISREF_P(var) && Z_REFCOUNT_P(var) == 1) {
530+
var = Z_REFVAL_P(var);
531+
}
532+
ZVAL_COPY(&copy, var);
526533
}
534+
535+
zend_hash_add_new(Z_ARRVAL(val), key, &copy);
527536
} ZEND_HASH_FOREACH_END();
537+
538+
if (zend_hash_num_elements(Z_ARRVAL(val))) {
539+
zend_hash_update(debug_info, ZSTR_KNOWN(ZEND_STR_STATIC), &val);
540+
} else {
541+
zval_ptr_dtor(&val);
542+
}
528543
}
529544

530545
if (Z_TYPE(closure->this_ptr) != IS_UNDEF) {

0 commit comments

Comments
 (0)