From f90dfba6cf6ccfc44e7e2b00530d2f5adac79fb6 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Fri, 29 Mar 2024 00:38:15 +0100 Subject: [PATCH] Fix GH-13827: Null pointer access of type 'zval' in phpdbg_frame We don't always have the line and filename in a backtrace frame, but phpdbg assumes we do. --- sapi/phpdbg/phpdbg_frame.c | 13 +++++++++++-- sapi/phpdbg/tests/gh13827.phpt | 30 ++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 sapi/phpdbg/tests/gh13827.phpt diff --git a/sapi/phpdbg/phpdbg_frame.c b/sapi/phpdbg/phpdbg_frame.c index 644668d8d14e5..3652d2b2bbaf2 100644 --- a/sapi/phpdbg/phpdbg_frame.c +++ b/sapi/phpdbg/phpdbg_frame.c @@ -274,7 +274,8 @@ void phpdbg_dump_backtrace(size_t num) /* {{{ */ Z_STR(startfile) = zend_string_init(startfilename, strlen(startfilename), 0); zend_hash_internal_pointer_reset_ex(Z_ARRVAL(zbacktrace), &position); - tmp = zend_hash_get_current_data_ex(Z_ARRVAL(zbacktrace), &position); + + zval *function_name = NULL; while ((tmp = zend_hash_get_current_data_ex(Z_ARRVAL(zbacktrace), &position))) { if (file) { /* userland */ phpdbg_out("frame #%d: ", i); @@ -289,10 +290,18 @@ void phpdbg_dump_backtrace(size_t num) /* {{{ */ file = zend_hash_str_find(Z_ARRVAL_P(tmp), ZEND_STRL("file")); line = zend_hash_str_find(Z_ARRVAL_P(tmp), ZEND_STRL("line")); + function_name = zend_hash_find(Z_ARRVAL_P(tmp), ZSTR_KNOWN(ZEND_STR_FUNCTION)); + zend_hash_move_forward_ex(Z_ARRVAL(zbacktrace), &position); } - phpdbg_writeln("frame #%d: {main} at %s:"ZEND_LONG_FMT, i, Z_STRVAL_P(file), Z_LVAL_P(line)); + /* This is possible for fibers' start closure for example, which have a frame that doesn't contain the info + * of which location stated the fiber if that stack frame is already torn down. same behaviour with debug_backtrace(). */ + if (file == NULL) { + phpdbg_writeln(" => %s (internal function)", Z_STRVAL_P(function_name)); + } else { + phpdbg_writeln("frame #%d: {main} at %s:"ZEND_LONG_FMT, i, Z_STRVAL_P(file), Z_LVAL_P(line)); + } zval_ptr_dtor_nogc(&zbacktrace); zend_string_release(Z_STR(startfile)); diff --git a/sapi/phpdbg/tests/gh13827.phpt b/sapi/phpdbg/tests/gh13827.phpt new file mode 100644 index 0000000000000..3d7017bf309f5 --- /dev/null +++ b/sapi/phpdbg/tests/gh13827.phpt @@ -0,0 +1,30 @@ +--TEST-- +GH-13827 (Null pointer access of type 'zval' in phpdbg_frame) +--FILE-- +start(); + +$fiber = null; +gc_collect_cycles(); + +?> +--PHPDBG-- +r +t +q +--EXPECTF-- +[Successful compilation of %s] +prompt> [Uncaught GracefulExit in on line 0: ] +>00006: Fiber::suspend(); + 00007: }); + 00008: +prompt> frame #0: {closure}() at %s:6 + => {closure} (internal function) +prompt>