Skip to content

Commit 564340b

Browse files
committed
Test fibers, move bailout context bump, remove hash guard
Unfortunately, we always need to check for the hash, because even if we're in the main context, the current guard may have been created in a fiber.
1 parent 1bc65f2 commit 564340b

File tree

6 files changed

+37
-5
lines changed

6 files changed

+37
-5
lines changed
File renamed without changes.

Zend/tests/gh14983_2.phpt

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
--TEST--
2+
GH-14983: Shutdown disregards guards active on bailout
3+
--FILE--
4+
<?php
5+
6+
class Foo {
7+
public function __get($prop) {
8+
echo "__set($prop)\n";
9+
if (Fiber::getCurrent()) {
10+
Fiber::suspend();
11+
echo "Resuming\n";
12+
}
13+
}
14+
}
15+
16+
$foo = new Foo();
17+
18+
$fiber = new Fiber(function () use ($foo) {
19+
$foo->bar;
20+
});
21+
22+
$value = $fiber->start();
23+
echo "Suspended\n";
24+
$foo->bar;
25+
$fiber->resume('test');
26+
27+
?>
28+
--EXPECT--
29+
__set(bar)
30+
Suspended
31+
__set(bar)
32+
Resuming

Zend/zend.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1240,6 +1240,7 @@ ZEND_API ZEND_COLD ZEND_NORETURN void _zend_bailout(const char *filename, uint32
12401240
CG(in_compilation) = 0;
12411241
CG(memoize_mode) = 0;
12421242
EG(current_execute_data) = NULL;
1243+
EG(guard_context) = (uint32_t)-1;
12431244
LONGJMP(*EG(bailout), FAILURE);
12441245
}
12451246
/* }}} */

Zend/zend_globals.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -297,8 +297,8 @@ struct _zend_executor_globals {
297297

298298
/* Guards are context dependent. I.e. if __get() is being called for an object
299299
* within a fiber, the guard will _not_ skip __get() in the main context. To
300-
* achieve this, we offset the guard string has by the guard context.
301-
* Additionally, shutdown will discard the current guards in the same way. */
300+
* achieve this, we offset the guard string hash by the guard context.
301+
* Additionally, bailout will discard the current guards in the same way. */
302302
uint32_t guard_context;
303303
uint32_t guard_context_counter;
304304

Zend/zend_object_handlers.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -578,8 +578,8 @@ ZEND_API uint32_t *zend_get_property_guard(zend_object *zobj, zend_string *membe
578578
zend_string *str = Z_STR_P(zv);
579579
if (EXPECTED(str == member) ||
580580
/* str and member don't necessarily have a pre-calculated hash value here */
581-
(EXPECTED(zend_string_equal_content(str, member))
582-
&& (EG(guard_context) == 0 || ZSTR_HASH(str) == ZSTR_HASH(member)))) {
581+
(EXPECTED(ZSTR_HASH(str) == ZSTR_HASH(member)
582+
&& zend_string_equal_content(str, member)))) {
583583
zend_string_release(member);
584584
return &Z_GUARD_P(zv);
585585
} else if (EXPECTED(Z_GUARD_P(zv) == 0)) {

main/main.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1858,7 +1858,6 @@ void php_request_shutdown(void *dummy)
18581858
* inside zend_executor callback functions.
18591859
*/
18601860
EG(current_execute_data) = NULL;
1861-
EG(guard_context) = (uint32_t)-1;
18621861

18631862
php_deactivate_ticks();
18641863

0 commit comments

Comments
 (0)