File tree Expand file tree Collapse file tree 5 files changed +83
-1
lines changed Expand file tree Collapse file tree 5 files changed +83
-1
lines changed Original file line number Diff line number Diff line change 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>
Original file line number Diff line number Diff line change 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>
Original file line number Diff line number Diff 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 )) {
Original file line number Diff line number Diff line change @@ -66,6 +66,7 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_deprecated_class_constant(const zend_
6666ZEND_API ZEND_COLD void ZEND_FASTCALL zend_false_to_array_deprecated (void );
6767ZEND_COLD void ZEND_FASTCALL zend_param_must_be_ref (const zend_function * func , uint32_t arg_num );
6868ZEND_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
7071ZEND_API bool ZEND_FASTCALL zend_verify_ref_assignable_zval (zend_reference * ref , zval * zv , bool strict );
7172
Original file line number Diff line number Diff 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
You can’t perform that action at this time.
0 commit comments