[php-src] Issue #24508: HTTP wrapper leaks dechunk filter when header parsing fails after Transfer-Encoding: chunked

From: Date: Wed, 21 Oct 2026 20:39:10 +0000
Subject: [php-src] Issue #24508: HTTP wrapper leaks dechunk filter when header parsing fails after Transfer-Encoding: chunked
Groups: php.bugs 
Request: Send a blank email to php-bugs+get-253065@lists.php.net to get a copy of this message
Issue: https://github.com/php/php-src/issues/24508 Author: IzieStratt ### Description The following code: server.php (run first, php server.php): ```php <?php $srv = stream_socket_server("tcp://127.0.0.1:18231", $errno, $errstr); $conn = stream_socket_accept($srv); while (($line = fgets($conn, 8192)) !== false) { if (trim($line) === '') break; } // Transfer-Encoding: chunked, then a malformed header line fwrite($conn, "HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\nBrokenHeaderNoColon\r\n\r\n"); fclose($conn); ``` client.php (debug build, php -d report_memleaks=1 client.php): ```php <?php @file_get_contents("http://127.0.0.1:18231/"); ``` Resulted in this output: ``` ext/standard/filters.c(1885) : Freeing 0x... (16 bytes), script=.../client.php main/streams/filter.c(267) : Freeing 0x... (80 bytes), script=.../client.php === Total 2 memory leaks detected === ``` But I expected this output instead: ``` (no leaks reported) ``` Root cause: when the response carries Transfer-Encoding: chunked, the wrapper creates a dechunk filter while parsing headers (php_stream_filter_create, ext/standard/http_fopen_wrapper.c:379 in 8.5.12, :366 on master). If a later header line is malformed, header_info.error is set, the caller closes the stream and jumps to out: (master :1052-1058). The out: cleanup only appends the filter to the stream's readfilters when stream != NULL (master :1257-1259), so on the error path the filter is never freed. Per failed request this leaks the php_stream_filter struct (80 bytes) plus the dechunk filter data (16 bytes). Reproduces on current master (8.7.0-dev) as well. Suggested patch (verified against master: repro reports 0 leaks after patching; well-formed chunked responses unaffected): ```diff --- a/ext/standard/http_fopen_wrapper.c +++ b/ext/standard/http_fopen_wrapper.c @@ -1230,6 +1230,13 @@ static php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, efree(header_info.location); } + /* On the error path stream is NULL and the filter is never appended + * to readfilters below, so it must be freed here. */ + if (header_info.transfer_encoding != NULL && stream == NULL) { + php_stream_filter_free(header_info.transfer_encoding); + header_info.transfer_encoding = NULL; + } + if (resource) { php_uri_struct_free(resource); } ``` ### PHP Version ```plain PHP 8.5.12 (also reproduces on master, 8.7.0-dev) ``` ### Operating System Linux x86_64

« previous php.bugs (#253065) next »