Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 2d8a93c

Browse files
Merge branch 'PHP-8.4'
* PHP-8.4: [ci skip] NEWS for GH-16055 Support stack limit in phpdbg SAPI
2 parents 8b41bca + 7c31e5f commit 2d8a93c

File tree

5 files changed

+83
-1
lines changed

5 files changed

+83
-1
lines changed
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
--TEST--
2+
GH-16041 001: Stack overflow in phpdbg
3+
--SKIPIF--
4+
<?php
5+
if (ini_get('zend.max_allowed_stack_size') === false) {
6+
die('skip No stack limit support');
7+
}
8+
?>
9+
--INI--
10+
zend.max_allowed_stack_size=512K
11+
--PHPDBG--
12+
set pagination off
13+
run
14+
continue
15+
quit
16+
--FILE--
17+
<?php
18+
19+
class Canary {
20+
public function __destruct() {
21+
new Canary();
22+
}
23+
}
24+
25+
new Canary();
26+
27+
?>
28+
--EXPECTF--
29+
[Successful compilation of %sgh16041_001.php]
30+
prompt> prompt> [Uncaught Error in %s on line %d: Maximum call stack size of %d bytes%s
31+
>00005: new Canary();
32+
00006: }
33+
00007: }
34+
prompt> [Uncaught Error in %s on line %d]
35+
Error: Maximum call stack size of %d bytes (zend.max_allowed_stack_size - zend.reserved_stack_size) reached. Infinite recursion? in %s:%d
36+
Stack trace:
37+
#0 %s(%d): Canary->__destruct()
38+
%a
39+
prompt>
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
--TEST--
2+
GH-16041 002: Stack overflow in phpdbg
3+
--SKIPIF--
4+
<?php
5+
if (ini_get('zend.max_allowed_stack_size') === false) {
6+
die('skip No stack limit support');
7+
}
8+
?>
9+
--INI--
10+
zend.max_allowed_stack_size=512K
11+
--PHPDBG--
12+
set pagination off
13+
run
14+
quit
15+
--FILE--
16+
<?php
17+
18+
function map() {
19+
array_map('map', [1]);
20+
}
21+
22+
try {
23+
map();
24+
} catch (\Throwable $e) {
25+
printf("%s: %s\n", $e::class, $e->getMessage());
26+
}
27+
28+
?>
29+
--EXPECTF--
30+
[Successful compilation of %sgh16041_002.php]
31+
prompt> prompt> Error: Maximum call stack size of %d bytes (zend.max_allowed_stack_size - zend.reserved_stack_size) reached. Infinite recursion?
32+
[Script ended normally]
33+
prompt>

‎Zend/zend_execute.c‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2500,7 +2500,7 @@ static zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_use_new_element_for_s
25002500
}
25012501

25022502
#ifdef ZEND_CHECK_STACK_LIMIT
2503-
static zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_call_stack_size_error(void)
2503+
zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_call_stack_size_error(void)
25042504
{
25052505
size_t max_stack_size = 0;
25062506
if ((uintptr_t) EG(stack_base) > (uintptr_t) EG(stack_limit)) {

‎Zend/zend_execute.h‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_deprecated_class_constant(const zend_
6666
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_false_to_array_deprecated(void);
6767
ZEND_COLD void ZEND_FASTCALL zend_param_must_be_ref(const zend_function *func, uint32_t arg_num);
6868
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_use_resource_as_offset(const zval *dim);
69+
zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_call_stack_size_error(void);
6970

7071
ZEND_API bool ZEND_FASTCALL zend_verify_ref_assignable_zval(zend_reference *ref, zval *zv, bool strict);
7172

‎sapi/phpdbg/phpdbg_prompt.c‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1652,6 +1652,15 @@ void phpdbg_execute_ex(zend_execute_data *execute_data) /* {{{ */
16521652

16531653
PHPDBG_G(in_execution) = 1;
16541654

1655+
#ifdef ZEND_CHECK_STACK_LIMIT
1656+
if (UNEXPECTED(zend_call_stack_overflowed(EG(stack_limit)))) {
1657+
zend_call_stack_size_error();
1658+
/* No opline was executed before exception */
1659+
EG(opline_before_exception) = NULL;
1660+
/* Fall through to handle exception below. */
1661+
}
1662+
#endif /* ZEND_CHECK_STACK_LIMIT */
1663+
16551664
while (1) {
16561665
zend_object *exception = EG(exception);
16571666

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /