Skip to content

Commit d3f1f3a

Browse files
committed
Fix phpGH-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. Closes phpGH-13831.
1 parent 100258f commit d3f1f3a

File tree

3 files changed

+45
-2
lines changed

3 files changed

+45
-2
lines changed

NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ PHP NEWS
1010
. Fixed bug GH-10495 (feof on OpenSSL stream hangs indefinitely).
1111
(Jakub Zelenka)
1212

13+
- PHPDBG:
14+
. Fixed bug GH-13827 (Null pointer access of type 'zval' in phpdbg_frame).
15+
(nielsdos)
16+
1317
- Streams:
1418
. Fixed bug GH-13264 (Part 1 - Memory leak on stream filter failure).
1519
(Jakub Zelenka)

sapi/phpdbg/phpdbg_frame.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,8 @@ void phpdbg_dump_backtrace(size_t num) /* {{{ */
274274
Z_STR(startfile) = zend_string_init(startfilename, strlen(startfilename), 0);
275275

276276
zend_hash_internal_pointer_reset_ex(Z_ARRVAL(zbacktrace), &position);
277-
tmp = zend_hash_get_current_data_ex(Z_ARRVAL(zbacktrace), &position);
277+
278+
zval *function_name = NULL;
278279
while ((tmp = zend_hash_get_current_data_ex(Z_ARRVAL(zbacktrace), &position))) {
279280
if (file) { /* userland */
280281
phpdbg_out("frame #%d: ", i);
@@ -289,10 +290,18 @@ void phpdbg_dump_backtrace(size_t num) /* {{{ */
289290

290291
file = zend_hash_str_find(Z_ARRVAL_P(tmp), ZEND_STRL("file"));
291292
line = zend_hash_str_find(Z_ARRVAL_P(tmp), ZEND_STRL("line"));
293+
function_name = zend_hash_find(Z_ARRVAL_P(tmp), ZSTR_KNOWN(ZEND_STR_FUNCTION));
294+
292295
zend_hash_move_forward_ex(Z_ARRVAL(zbacktrace), &position);
293296
}
294297

295-
phpdbg_writeln("frame #%d: {main} at %s:"ZEND_LONG_FMT, i, Z_STRVAL_P(file), Z_LVAL_P(line));
298+
/* This is possible for fibers' start closure for example, which have a frame that doesn't contain the info
299+
* of which location stated the fiber if that stack frame is already torn down. same behaviour with debug_backtrace(). */
300+
if (file == NULL) {
301+
phpdbg_writeln(" => %s (internal function)", Z_STRVAL_P(function_name));
302+
} else {
303+
phpdbg_writeln("frame #%d: {main} at %s:"ZEND_LONG_FMT, i, Z_STRVAL_P(file), Z_LVAL_P(line));
304+
}
296305

297306
zval_ptr_dtor_nogc(&zbacktrace);
298307
zend_string_release(Z_STR(startfile));

sapi/phpdbg/tests/gh13827.phpt

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
--TEST--
2+
GH-13827 (Null pointer access of type 'zval' in phpdbg_frame)
3+
--FILE--
4+
<?php
5+
6+
$fiber = new Fiber(function () {
7+
$fiber = Fiber::getCurrent();
8+
9+
Fiber::suspend();
10+
});
11+
12+
$fiber->start();
13+
14+
$fiber = null;
15+
gc_collect_cycles();
16+
17+
?>
18+
--PHPDBG--
19+
r
20+
t
21+
q
22+
--EXPECTF--
23+
[Successful compilation of %s]
24+
prompt> [Uncaught GracefulExit in on line 0: ]
25+
>00006: Fiber::suspend();
26+
00007: });
27+
00008:
28+
prompt> frame #0: {closure}() at %s:6
29+
=> {closure} (internal function)
30+
prompt>

0 commit comments

Comments
 (0)