Skip to content

Commit 213063f

Browse files
committed
Fix #81076 Invalid implicit binds cause incorrect count in static vars of closure debug info
1 parent cfd4d3d commit 213063f

File tree

3 files changed

+35
-7
lines changed

3 files changed

+35
-7
lines changed

Diff for: NEWS

+4
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ PHP NEWS
22
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
33
?? ??? 2021, PHP 8.0.8
44

5+
- Core:
6+
. Fixed bug #81076 (incorrect debug info on Closures with implicit binds).
7+
(krakjoe)
8+
59
- Opcache:
610
. Fixed bug #80968 (JIT segfault with return from required file). (Dmitry)
711

Diff for: Zend/tests/bug81076.phpt

+9
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+
}

Diff for: Zend/zend_closures.c

+22-7
Original file line numberDiff line numberDiff line change
@@ -550,16 +550,31 @@ static HashTable *zend_closure_get_debug_info(zend_object *object, int *is_temp)
550550

551551
if (closure->func.type == ZEND_USER_FUNCTION && closure->func.op_array.static_variables) {
552552
zval *var;
553-
HashTable *static_variables =
554-
ZEND_MAP_PTR_GET(closure->func.op_array.static_variables_ptr);
555-
ZVAL_ARR(&val, zend_array_dup(static_variables));
556-
zend_hash_update(debug_info, ZSTR_KNOWN(ZEND_STR_STATIC), &val);
557-
ZEND_HASH_FOREACH_VAL(Z_ARRVAL(val), var) {
553+
zend_string *key;
554+
HashTable *static_variables = ZEND_MAP_PTR_GET(closure->func.op_array.static_variables_ptr);
555+
556+
array_init(&val);
557+
558+
ZEND_HASH_FOREACH_STR_KEY_VAL(static_variables, key, var) {
559+
zval copy;
560+
558561
if (Z_TYPE_P(var) == IS_CONSTANT_AST) {
559-
zval_ptr_dtor(var);
560-
ZVAL_STRING(var, "<constant ast>");
562+
ZVAL_STRING(&copy, "<constant ast>");
563+
} else {
564+
if (Z_ISREF_P(var) && Z_REFCOUNT_P(var) == 1) {
565+
var = Z_REFVAL_P(var);
566+
}
567+
ZVAL_COPY(&copy, var);
561568
}
569+
570+
zend_hash_add_new(Z_ARRVAL(val), key, &copy);
562571
} ZEND_HASH_FOREACH_END();
572+
573+
if (zend_hash_num_elements(Z_ARRVAL(val))) {
574+
zend_hash_update(debug_info, ZSTR_KNOWN(ZEND_STR_STATIC), &val);
575+
} else {
576+
zval_ptr_dtor(&val);
577+
}
563578
}
564579

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

0 commit comments

Comments
 (0)