Skip to content

Commit a8f0634

Browse files
committed
Merge remote-tracking branch 'origin/PHP-8.0' into PHP-8.1
2 parents 86d470f + 12b0f1b commit a8f0634

File tree

4 files changed

+80
-5
lines changed

4 files changed

+80
-5
lines changed

Zend/zend_observer.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,10 @@ ZEND_API void ZEND_FASTCALL zend_observer_fcall_end(
228228
current_observed_frame = NULL;
229229
} else {
230230
zend_execute_data *ex = execute_data->prev_execute_data;
231-
while (ex && !ex->func) {
231+
while (ex && (!ex->func || ex->func->type == ZEND_INTERNAL_FUNCTION
232+
|| !ZEND_OBSERVABLE_FN(ex->func->common.fn_flags)
233+
|| !ZEND_OBSERVER_DATA(&ex->func->op_array)
234+
|| ZEND_OBSERVER_DATA(&ex->func->op_array) == ZEND_OBSERVER_NOT_OBSERVED)) {
232235
ex = ex->prev_execute_data;
233236
}
234237
current_observed_frame = ex;

ext/zend_test/observer.c

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -181,10 +181,16 @@ static zend_observer_fcall_handlers observer_fcall_init(zend_execute_data *execu
181181

182182
if (ZT_G(observer_observe_all)) {
183183
return (zend_observer_fcall_handlers){observer_begin, observer_end};
184-
} else if (ZT_G(observer_observe_includes) && !fbc->common.function_name) {
185-
return (zend_observer_fcall_handlers){observer_begin, observer_end};
186-
} else if (ZT_G(observer_observe_functions) && fbc->common.function_name) {
187-
return (zend_observer_fcall_handlers){observer_begin, observer_end};
184+
} else if (fbc->common.function_name) {
185+
if (ZT_G(observer_observe_functions)) {
186+
return (zend_observer_fcall_handlers){observer_begin, observer_end};
187+
} else if (ZT_G(observer_observe_function_names) && zend_hash_exists(ZT_G(observer_observe_function_names), fbc->common.function_name)) {
188+
return (zend_observer_fcall_handlers){observer_begin, observer_end};
189+
}
190+
} else {
191+
if (ZT_G(observer_observe_includes)) {
192+
return (zend_observer_fcall_handlers){observer_begin, observer_end};
193+
}
188194
}
189195
return (zend_observer_fcall_handlers){NULL, NULL};
190196
}
@@ -250,12 +256,33 @@ static void fiber_suspend_observer(zend_fiber_context *from, zend_fiber_context
250256
}
251257
}
252258

259+
static ZEND_INI_MH(zend_test_observer_OnUpdateCommaList)
260+
{
261+
zend_array **p = (zend_array **) ZEND_INI_GET_ADDR();
262+
if (*p) {
263+
zend_hash_release(*p);
264+
}
265+
*p = NULL;
266+
if (new_value && ZSTR_LEN(new_value)) {
267+
*p = malloc(sizeof(HashTable));
268+
_zend_hash_init(*p, 8, ZVAL_PTR_DTOR, 1);
269+
const char *start = ZSTR_VAL(new_value), *ptr;
270+
while ((ptr = strchr(start, ','))) {
271+
zend_hash_str_add_empty_element(*p, start, ptr - start);
272+
start = ptr + 1;
273+
}
274+
zend_hash_str_add_empty_element(*p, start, ZSTR_VAL(new_value) + ZSTR_LEN(new_value) - start);
275+
}
276+
return SUCCESS;
277+
}
278+
253279
PHP_INI_BEGIN()
254280
STD_PHP_INI_BOOLEAN("zend_test.observer.enabled", "0", PHP_INI_SYSTEM, OnUpdateBool, observer_enabled, zend_zend_test_globals, zend_test_globals)
255281
STD_PHP_INI_BOOLEAN("zend_test.observer.show_output", "1", PHP_INI_SYSTEM, OnUpdateBool, observer_show_output, zend_zend_test_globals, zend_test_globals)
256282
STD_PHP_INI_BOOLEAN("zend_test.observer.observe_all", "0", PHP_INI_SYSTEM, OnUpdateBool, observer_observe_all, zend_zend_test_globals, zend_test_globals)
257283
STD_PHP_INI_BOOLEAN("zend_test.observer.observe_includes", "0", PHP_INI_SYSTEM, OnUpdateBool, observer_observe_includes, zend_zend_test_globals, zend_test_globals)
258284
STD_PHP_INI_BOOLEAN("zend_test.observer.observe_functions", "0", PHP_INI_SYSTEM, OnUpdateBool, observer_observe_functions, zend_zend_test_globals, zend_test_globals)
285+
STD_PHP_INI_ENTRY("zend_test.observer.observe_function_names", "", PHP_INI_SYSTEM, zend_test_observer_OnUpdateCommaList, observer_observe_function_names, zend_zend_test_globals, zend_test_globals)
259286
STD_PHP_INI_BOOLEAN("zend_test.observer.show_return_type", "0", PHP_INI_SYSTEM, OnUpdateBool, observer_show_return_type, zend_zend_test_globals, zend_test_globals)
260287
STD_PHP_INI_BOOLEAN("zend_test.observer.show_return_value", "0", PHP_INI_SYSTEM, OnUpdateBool, observer_show_return_value, zend_zend_test_globals, zend_test_globals)
261288
STD_PHP_INI_BOOLEAN("zend_test.observer.show_init_backtrace", "0", PHP_INI_SYSTEM, OnUpdateBool, observer_show_init_backtrace, zend_zend_test_globals, zend_test_globals)

ext/zend_test/php_test.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ ZEND_BEGIN_MODULE_GLOBALS(zend_test)
3838
int observer_observe_all;
3939
int observer_observe_includes;
4040
int observer_observe_functions;
41+
zend_array *observer_observe_function_names;
4142
int observer_show_return_type;
4243
int observer_show_return_value;
4344
int observer_show_init_backtrace;

ext/zend_test/tests/bug81435.phpt

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
--TEST--
2+
Bug #81435 (Observer current_observed_frame may point to an old (overwritten) frame)
3+
--INI--
4+
memory_limit=20M
5+
zend_test.observer.enabled=1
6+
zend_test.observer.observe_function_names=a,d
7+
--FILE--
8+
<?php
9+
10+
function d() {} // observed
11+
12+
function c() {
13+
d();
14+
}
15+
16+
function b() {
17+
c();
18+
}
19+
20+
function bailout(...$args) {
21+
array_map("str_repeat", ["\xFF"], [100000000]);
22+
}
23+
24+
function a() { // observed (first_observed_frame)
25+
b();
26+
bailout(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); // overwrite the vm_stack containing prev_execute_data
27+
}
28+
29+
a();
30+
31+
?>
32+
--EXPECTF--
33+
<!-- init '%s' -->
34+
<!-- init a() -->
35+
<a>
36+
<!-- init b() -->
37+
<!-- init c() -->
38+
<!-- init d() -->
39+
<d>
40+
</d>
41+
<!-- init bailout() -->
42+
43+
Fatal error: Allowed memory size of 20971520 bytes exhausted at %s (tried to allocate %d bytes) in %s on line %d
44+
</a>

0 commit comments

Comments
 (0)