[php-src] Issue #21504: PHP crashes with a use-after-free in `-e` mode on certain scripts

[email protected] (derickr)
Newsgroups php.bugs
Message-ID <I9l78irJAN5o51rkCM3gdItPNrsssGrUIhx1WsdLXrg@main.internal.php.net>
Issue: https://github.com/php/php-src/issues/21504
Author: derickr

### Description

The following code:

```php
<?php

function test($t) {
    echo $t.PHP_EOL;
}

'1234' |> test(...);
```

When run with:

```
USE_ZEND_ALLOC=0 valgrind php -n -e test.php
```

This was reported to me in https://bugs.xdebug.org/view.php?id=2402, but it's not a bug in Xdebug, as:

- The `-n` turns off all extensions, including Xdebug, so it's not active.
- The `-e` turns on "extended instructions", which Xdebug does turn on so that it can do step debugging, however, it's also turn-on-able for other reasons.

Resulted in this output:
```
==3562624== Invalid read of size 4
==3562624==    at 0x4C40F1E: zend_gc_delref (zend_types.h:1383)
==3562624==    by 0x4C40FF9: zval_delref_p (zend_types.h:1419)
==3562624==    by 0x4C41557: zval_ptr_dtor_nogc (zend_variables.h:35)
==3562624==    by 0x4C4647E: zend_ast_destroy (zend_ast.c:1381)
==3562624==    by 0x4C464D6: zend_ast_destroy (zend_ast.c:1388)
==3562624==    by 0x4D74A52: zend_compile (zend_language_scanner.l:634)
==3562624==    by 0x4D74B2D: compile_file (zend_language_scanner.l:662)
==3562624==    by 0x4880BE5: phar_compile_file (phar.c:3305)
==3562624==    by 0x4DCD268: zend_execute_script (zend.c:1970)
==3562624==    by 0x4B80238: php_execute_script_ex (main.c:2641)
==3562624==    by 0x4B80369: php_execute_script (main.c:2681)
==3562624==    by 0x4DCF8C8: do_cli (php_cli.c:951)
==3562624==    by 0x4DD0836: main (php_cli.c:1362)
==3562624==  Address 0xc1a5a30 is 0 bytes inside a block of size 32 free'd
==3562624==    at 0x41E587F: free (vg_replace_malloc.c:989)
==3562624==    by 0x4C2D9D0: __zend_free (zend_alloc.c:3571)
==3562624==    by 0x4C2BC76: _efree (zend_alloc.c:2790)
==3562624==    by 0x4DBB52E: zend_string_release (zend_string.h:339)
==3562624==    by 0x4DBBFAA: zend_new_interned_string_request (zend_string.c:246)
==3562624==    by 0x4C6488B: zval_make_interned_string (zend_compile.c:566)
==3562624==    by 0x4C64906: zend_insert_literal (zend_compile.c:578)
==3562624==    by 0x4C64A0B: zend_add_literal (zend_compile.c:599)
==3562624==    by 0x4C69116: zend_emit_op (zend_compile.c:2291)
==3562624==    by 0x4C6CDEA: zend_compile_args (zend_compile.c:3897)
==3562624==    by 0x4C6D0C1: zend_compile_call_common (zend_compile.c:3972)
==3562624==    by 0x4C70C0E: zend_compile_call (zend_compile.c:5232)
==3562624==    by 0x4C8429B: zend_compile_var_inner (zend_compile.c:11980)
==3562624==    by 0x4C843B3: zend_compile_var (zend_compile.c:12011)
==3562624==    by 0x4C83D69: zend_compile_expr_inner (zend_compile.c:11830)
==3562624==    by 0x4C840D3: zend_compile_expr (zend_compile.c:11949)
==3562624==    by 0x4C7414B: zend_compile_pipe (zend_compile.c:6543)
==3562624==    by 0x4C8407A: zend_compile_expr_inner (zend_compile.c:11936)
==3562624==    by 0x4C840D3: zend_compile_expr (zend_compile.c:11949)
==3562624==    by 0x4C838EB: zend_compile_stmt (zend_compile.c:11791)
==3562624==    by 0x4C833C8: zend_compile_top_stmt (zend_compile.c:11675)
==3562624==    by 0x4C83329: zend_compile_top_stmt (zend_compile.c:11661)
==3562624==    by 0x4D749D9: zend_compile (zend_language_scanner.l:622)
==3562624==    by 0x4D74B2D: compile_file (zend_language_scanner.l:662)
==3562624==    by 0x4880BE5: phar_compile_file (phar.c:3305)
==3562624==    by 0x4DCD268: zend_execute_script (zend.c:1970)
==3562624==    by 0x4B80238: php_execute_script_ex (main.c:2641)
==3562624==    by 0x4B80369: php_execute_script (main.c:2681)
==3562624==    by 0x4DCF8C8: do_cli (php_cli.c:951)
==3562624==    by 0x4DD0836: main (php_cli.c:1362)
==3562624==  Block was alloc'd at
==3562624==    at 0x41E2818: malloc (vg_replace_malloc.c:446)
==3562624==    by 0x4C2D89E: __zend_malloc (zend_alloc.c:3543)
==3562624==    by 0x4C2BBF0: _emalloc (zend_alloc.c:2780)
==3562624==    by 0x4D72DB7: zend_string_alloc (zend_string.h:167)
==3562624==    by 0x4D72E2A: zend_string_init (zend_string.h:189)
==3562624==    by 0x4D77565: lex_scan (zend_language_scanner.l:2573)
==3562624==    by 0x4C68669: zendlex (zend_compile.c:2038)
==3562624==    by 0x4D69799: zendparse (zend_language_parser.c:5588)
==3562624==    by 0x4D74909: zend_compile (zend_language_scanner.l:603)
==3562624==    by 0x4D74B2D: compile_file (zend_language_scanner.l:662)
==3562624==    by 0x4880BE5: phar_compile_file (phar.c:3305)
==3562624==    by 0x4DCD268: zend_execute_script (zend.c:1970)
==3562624==    by 0x4B80238: php_execute_script_ex (main.c:2641)
==3562624==    by 0x4B80369: php_execute_script (main.c:2681)
==3562624==    by 0x4DCF8C8: do_cli (php_cli.c:951)
==3562624==    by 0x4DD0836: main (php_cli.c:1362)
==3562624== 
php: /home/derick/dev/php/php-src.git/Zend/zend_types.h:1383: zend_gc_delref: Assertion `p->refcount > 0' failed.
==3562624== 
==3562624== Process terminating with default action of signal 6 (SIGABRT)
==3562624==    at 0x81453BC: __pthread_kill_implementation (pthread_kill.c:44)
==3562624==    by 0x80EE941: raise (raise.c:26)
==3562624==    by 0x80D64AB: abort (abort.c:77)
==3562624==    by 0x80D641F: __assert_fail_base.cold (assert.c:118)
==3562624==    by 0x4C40F48: zend_gc_delref (zend_types.h:1383)
==3562624==    by 0x4C40FF9: zval_delref_p (zend_types.h:1419)
==3562624==    by 0x4C41557: zval_ptr_dtor_nogc (zend_variables.h:35)
==3562624==    by 0x4C4647E: zend_ast_destroy (zend_ast.c:1381)
==3562624==    by 0x4C464D6: zend_ast_destroy (zend_ast.c:1388)
==3562624==    by 0x4D74A52: zend_compile (zend_language_scanner.l:634)
==3562624==    by 0x4D74B2D: compile_file (zend_language_scanner.l:662)
==3562624==    by 0x4880BE5: phar_compile_file (phar.c:3305)
==3562624==    by 0x4DCD268: zend_execute_script (zend.c:1970)
==3562624==    by 0x4B80238: php_execute_script_ex (main.c:2641)
==3562624==    by 0x4B80369: php_execute_script (main.c:2681)
==3562624==    by 0x4DCF8C8: do_cli (php_cli.c:951)
==3562624==    by 0x4DD0836: main (php_cli.c:1362)
==3562624== 
==3562624== HEAP SUMMARY:
==3562624==     in use at exit: 5,218,545 bytes in 36,018 blocks
==3562624==   total heap usage: 41,131 allocs, 5,113 frees, 6,514,971 bytes allocated
```

But I expected this output instead:
```
1234
```


### PHP Version

```plain
PHP 8.5.5-dev (cli) (built: Mar 23 2026 00:44:22) (NTS DEBUG)
Copyright (c) The PHP Group
Zend Engine v4.5.5-dev, Copyright (c) Zend Technologies
    with Zend OPcache v8.5.5-dev, Copyright (c), by Zend Technologies
```

### Operating System

Debian forky/sid
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.