Skip to content

Commit aa37b64

Browse files
committed
Fix GH-22118: Unregister equivalent tick closures
1 parent 4659762 commit aa37b64

2 files changed

Lines changed: 40 additions & 0 deletions

File tree

ext/standard/basic_functions.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1639,6 +1639,15 @@ static int user_tick_function_compare(user_tick_function_entry * tick_fe1, user_
16391639
{
16401640
bool is_equal = zend_fcc_equals(&tick_fe1->fci_cache, &tick_fe2->fci_cache);
16411641

1642+
if (!is_equal && tick_fe1->fci_cache.closure && tick_fe2->fci_cache.closure) {
1643+
zval closure1, closure2;
1644+
1645+
ZVAL_OBJ(&closure1, tick_fe1->fci_cache.closure);
1646+
ZVAL_OBJ(&closure2, tick_fe2->fci_cache.closure);
1647+
1648+
is_equal = zend_compare_objects(&closure1, &closure2) == 0;
1649+
}
1650+
16421651
if (is_equal && tick_fe1->calling) {
16431652
zend_throw_error(NULL, "Registered tick function cannot be unregistered while it is being executed");
16441653
return false;
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
--TEST--
2+
GH-22118: unregister_tick_function() unregisters equivalent first-class method callables
3+
--FILE--
4+
<?php
5+
declare(ticks=1);
6+
7+
class TickTest
8+
{
9+
public function kick(): void
10+
{
11+
echo "tick\n";
12+
}
13+
14+
public function run(): void
15+
{
16+
register_tick_function($this->kick(...));
17+
echo "registered\n";
18+
unregister_tick_function($this->kick(...));
19+
echo "unregistered\n";
20+
}
21+
}
22+
23+
(new TickTest())->run();
24+
echo "done\n";
25+
?>
26+
--EXPECT--
27+
tick
28+
registered
29+
tick
30+
unregistered
31+
done

0 commit comments

Comments
 (0)