Fix #81076 Invalid implicit binds cause incorrect count in static vars of closure debug info

This commit is contained in:
Joe Watkins 2021-05-24 07:26:56 +02:00
parent cfd4d3df0b
commit 213063f6ca
No known key found for this signature in database
GPG key ID: F9BA0ADA31CBD89E
3 changed files with 35 additions and 7 deletions

4
NEWS
View file

@ -2,6 +2,10 @@ PHP NEWS
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
?? ??? 2021, PHP 8.0.8
- Core:
. Fixed bug #81076 (incorrect debug info on Closures with implicit binds).
(krakjoe)
- Opcache:
. Fixed bug #80968 (JIT segfault with return from required file). (Dmitry)

9
Zend/tests/bug81076.phpt Normal file
View file

@ -0,0 +1,9 @@
--TEST--
Bug #81076 Invalid implicit binds cause incorrect static var count in closure debug info
--FILE--
<?php
var_dump(fn() => [$why, $do, $we, $count]);
?>
--EXPECT--
object(Closure)#1 (0) {
}

View file

@ -550,16 +550,31 @@ static HashTable *zend_closure_get_debug_info(zend_object *object, int *is_temp)
if (closure->func.type == ZEND_USER_FUNCTION && closure->func.op_array.static_variables) {
zval *var;
HashTable *static_variables =
ZEND_MAP_PTR_GET(closure->func.op_array.static_variables_ptr);
ZVAL_ARR(&val, zend_array_dup(static_variables));
zend_hash_update(debug_info, ZSTR_KNOWN(ZEND_STR_STATIC), &val);
ZEND_HASH_FOREACH_VAL(Z_ARRVAL(val), var) {
zend_string *key;
HashTable *static_variables = ZEND_MAP_PTR_GET(closure->func.op_array.static_variables_ptr);
array_init(&val);
ZEND_HASH_FOREACH_STR_KEY_VAL(static_variables, key, var) {
zval copy;
if (Z_TYPE_P(var) == IS_CONSTANT_AST) {
zval_ptr_dtor(var);
ZVAL_STRING(var, "<constant ast>");
ZVAL_STRING(&copy, "<constant ast>");
} else {
if (Z_ISREF_P(var) && Z_REFCOUNT_P(var) == 1) {
var = Z_REFVAL_P(var);
}
ZVAL_COPY(&copy, var);
}
zend_hash_add_new(Z_ARRVAL(val), key, &copy);
} ZEND_HASH_FOREACH_END();
if (zend_hash_num_elements(Z_ARRVAL(val))) {
zend_hash_update(debug_info, ZSTR_KNOWN(ZEND_STR_STATIC), &val);
} else {
zval_ptr_dtor(&val);
}
}
if (Z_TYPE(closure->this_ptr) != IS_UNDEF) {