php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #61636 readfile() resp. fpassthru() try to allocate complete file into memory
Submitted: 2012-04-05 12:31 UTC Modified: 2013-04-15 07:06 UTC
Votes:11
Avg. Score:3.9 ± 1.2
Reproduced:10 of 10 (100.0%)
Same Version:1 (10.0%)
Same OS:5 (50.0%)
From: kontrollfreak at arcor dot de Assigned:
Status: Open Package: Apache related
PHP Version: master-Git-2012-04-05 (snap) OS: Windows XP SP3
Private report: No CVE-ID: None
Have you experienced this issue?
Rate the importance of this bug to you:

 [2012-04-05 12:31 UTC] kontrollfreak at arcor dot de
Description:
------------
Tested on:
- PHP 5.5.0dev (r324251) as Apache 2.2 module
- Apache 2.2.22

This bug applies to the Apache module on Windows only. The cgi version does not show this behavior.

I narrowed it down to PHP 5.2.10. Before that version the test script runs without error.

Test script:
---------------
<?php

//test.bin has 200 MB
readfile('test.bin');

?>

Expected result:
----------------
No error

Actual result:
--------------
Immediate result (doesn't even begin to load the file):

Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 209719296 bytes) in C:*\readfile.php on line 4

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2012-11-09 23:52 UTC] kv3981 at gmail dot com
Same issue on
--------------
- Debian Squeeze 6.0.6
- PHP 5.3.3-7+squeeze14
- Default php.ini, with memory_limit 128M 128M

Workaround
-----------
<?php
// Reads large file, fixes: https://bugs.php.net/bug.php?id=61636	
function readlargefile($fullfile) {
	$fp = fopen($fullfile, 'rb');
	
	if ($fp) {
		while (!feof($fp)) {
			print(fread($fp, 2097152));
		}
	
		fclose($fp);
	}
}
?>
 [2013-02-10 20:00 UTC] fredericg_99 at yahoo dot fr
I can confirm that the problem exists on PHP 5.3.16.
However, the problem does not appear for every files, but once it appears on a file, it applies for every attempts on that file (and not necessarily for the others).
The proposed workaround works.
 [2013-04-14 11:18 UTC] kontrollfreak at arcor dot de
(Windows only)
kv3981 at gmail dot com's solution works as long as the transfer does not take longer than max_execution_time.
 [2013-04-14 12:55 UTC] pajoye@php.net
-Status: Open +Status: Feedback
 [2013-04-14 12:55 UTC] pajoye@php.net
Be sure to disable output buffering, see http://www.php.net/readfile
 [2013-04-14 13:59 UTC] kontrollfreak at arcor dot de
In reply to [2013-04-14 12:55 UTC] pajoye@php.net:

During the test output buffering was disabled by the following snippet.

Disable output buffering:
-------------------------
<?php
while (ob_get_level())
 ob_end_flush();
?>
 [2013-04-14 13:59 UTC] kontrollfreak at arcor dot de
-: nachnamev2 at t-online dot de +: kontrollfreak at arcor dot de -Status: Feedback +Status: Open
 [2013-04-15 04:21 UTC] pajoye@php.net
-Status: Open +Status: Feedback
 [2013-04-15 04:21 UTC] pajoye@php.net
And you still got the out of memory error?
 [2013-04-15 07:06 UTC] kontrollfreak at arcor dot de
To be sure, I reran the test this morning under following conditions:
---------------------------------------------------------------------

- Windows XP SP3
- Apache 2.4.4 from http://www.apachelounge.com/download/win32/binaries/httpd-2.4.4-win32.zip
- PHP 5.4.14 from http://windows.php.net/downloads/releases/php-5.4.14-Win32-VC9-x86.zip

httpd.conf:
-----------
LoadModule authz_core_module modules/mod_authz_core.so
LoadModule php5_module       modules/php5apache2_4.dll

Listen 80

LogLevel trace8

DocumentRoot htdocs

<FilesMatch "\.php$">
    SetHandler application/x-httpd-php
</FilesMatch>

php.ini:
--------
*empty*

Test script:
------------
<?php

error_reporting(-1);

while(ob_get_level())
    ob_end_flush();

header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="test.bin"');
header('Content-Length: 209715200');
readfile('test.bin');

?>

Expected result:
----------------
A download of file "test.bin" containing 200 MB of NUL bytes

Actual result:
--------------
The result has changed. I do not get the out of memory error anymore. Instead Firefox 20.0.1 shows the following:

The connection was reset
    The connection to the server was reset while the page was loading.

Apache error.log:
-----------------
[Mon Apr 15 09:03:29.719610 2013] [core:trace3] [pid 2588:tid 1884] core.c(3034): Setting LogLevel for all modules to trace8
[Mon Apr 15 09:03:29.749653 2013] [mpm_winnt:notice] [pid 2588:tid 1884] AH00455: Apache/2.4.4 (Win32) PHP/5.4.14 configured -- resuming normal operations
[Mon Apr 15 09:03:29.749653 2013] [mpm_winnt:notice] [pid 2588:tid 1884] AH00456: Server built: Feb 23 2013 16:24:03
[Mon Apr 15 09:03:29.749653 2013] [core:notice] [pid 2588:tid 1884] AH00094: Command line: 'httpd -d C:/Apache24'
[Mon Apr 15 09:03:29.759668 2013] [mpm_winnt:notice] [pid 2588:tid 1884] AH00418: Parent: Created child process 2576
[Mon Apr 15 09:03:29.759668 2013] [mpm_winnt:debug] [pid 2588:tid 1884] mpm_winnt.c(422): AH00402: Parent: Sent the scoreboard to the child
[Mon Apr 15 09:03:30.230345 2013] [core:trace3] [pid 2576:tid 1868] core.c(3034): Setting LogLevel for all modules to trace8
[Mon Apr 15 09:03:30.280417 2013] [core:trace3] [pid 2576:tid 1868] core.c(3034): Setting LogLevel for all modules to trace8
[Mon Apr 15 09:03:30.300445 2013] [mpm_winnt:debug] [pid 2576:tid 1868] mpm_winnt.c(1708): AH00453: Child process is running
[Mon Apr 15 09:03:30.300445 2013] [mpm_winnt:debug] [pid 2588:tid 1884] mpm_winnt.c(505): AH00408: Parent: Duplicating socket 1892 (0.0.0.0:80) and sending it to child process 2576
[Mon Apr 15 09:03:30.300445 2013] [mpm_winnt:debug] [pid 2588:tid 1884] mpm_winnt.c(524): AH00411: Parent: Sent 1 listeners to child 2576
[Mon Apr 15 09:03:30.300445 2013] [core:trace4] [pid 2588:tid 1884] mpm_common.c(526): mpm child 2576 (gen 0/slot 0) started
[Mon Apr 15 09:03:30.300445 2013] [mpm_winnt:debug] [pid 2576:tid 1868] mpm_winnt.c(343): AH00391: Child: Retrieved our scoreboard from the parent.
[Mon Apr 15 09:03:30.300445 2013] [mpm_winnt:debug] [pid 2576:tid 1868] mpm_winnt.c(458): AH00403: Child: Waiting for data for listening socket 0.0.0.0:80
[Mon Apr 15 09:03:30.300445 2013] [mpm_winnt:debug] [pid 2576:tid 1868] mpm_winnt.c(483): AH00407: Child: retrieved 1 listeners from parent
[Mon Apr 15 09:03:30.300445 2013] [mpm_winnt:debug] [pid 2576:tid 1868] child.c(955): AH00352: Child: Acquired the start mutex.
[Mon Apr 15 09:03:30.300445 2013] [mpm_winnt:notice] [pid 2576:tid 1868] AH00354: Child: Starting 64 worker threads.
[Mon Apr 15 09:03:30.310460 2013] [mpm_winnt:debug] [pid 2576:tid 1252] child.c(354): AH00334: Child: Accept thread listening on 0.0.0.0:80 using AcceptFilter data
[Mon Apr 15 09:03:33.444967 2013] [core:trace5] [pid 2576:tid 1260] protocol.c(622): [client 127.0.0.1:1146] Request received from client: GET /test.php HTTP/1.1
[Mon Apr 15 09:03:33.444967 2013] [http:trace4] [pid 2576:tid 1260] http_request.c(300): [client 127.0.0.1:1146] Headers received from client:
[Mon Apr 15 09:03:33.444967 2013] [http:trace4] [pid 2576:tid 1260] http_request.c(303): [client 127.0.0.1:1146]   Host: localhost
[Mon Apr 15 09:03:33.444967 2013] [http:trace4] [pid 2576:tid 1260] http_request.c(303): [client 127.0.0.1:1146]   User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:20.0) Gecko/20100101 Firefox/20.0
[Mon Apr 15 09:03:33.444967 2013] [http:trace4] [pid 2576:tid 1260] http_request.c(303): [client 127.0.0.1:1146]   Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
[Mon Apr 15 09:03:33.444967 2013] [http:trace4] [pid 2576:tid 1260] http_request.c(303): [client 127.0.0.1:1146]   Accept-Language: en-US,en;q=0.5
[Mon Apr 15 09:03:33.444967 2013] [http:trace4] [pid 2576:tid 1260] http_request.c(303): [client 127.0.0.1:1146]   Accept-Encoding: gzip, deflate
[Mon Apr 15 09:03:33.444967 2013] [http:trace4] [pid 2576:tid 1260] http_request.c(303): [client 127.0.0.1:1146]   Connection: keep-alive
[Mon Apr 15 09:03:33.444967 2013] [http:trace4] [pid 2576:tid 1260] http_request.c(303): [client 127.0.0.1:1146]   Cache-Control: max-age=0
[Mon Apr 15 09:03:33.444967 2013] [authz_core:debug] [pid 2576:tid 1260] mod_authz_core.c(827): [client 127.0.0.1:1146] AH01628: authorization result: granted (no directives)
[Mon Apr 15 09:03:33.444967 2013] [core:trace3] [pid 2576:tid 1260] request.c(225): [client 127.0.0.1:1146] request authorized without authentication by access_checker_ex hook: /test.php
[Mon Apr 15 09:03:33.444967 2013] [http:trace3] [pid 2576:tid 1260] http_filters.c(960): [client 127.0.0.1:1146] Response sent with status 200, headers:
[Mon Apr 15 09:03:33.444967 2013] [http:trace5] [pid 2576:tid 1260] http_filters.c(969): [client 127.0.0.1:1146]   Date: Mon, 15 Apr 2013 07:03:33 GMT
[Mon Apr 15 09:03:33.444967 2013] [http:trace5] [pid 2576:tid 1260] http_filters.c(972): [client 127.0.0.1:1146]   Server: Apache/2.4.4 (Win32) PHP/5.4.14
[Mon Apr 15 09:03:33.444967 2013] [http:trace4] [pid 2576:tid 1260] http_filters.c(804): [client 127.0.0.1:1146]   X-Powered-By: PHP/5.4.14
[Mon Apr 15 09:03:33.444967 2013] [http:trace4] [pid 2576:tid 1260] http_filters.c(804): [client 127.0.0.1:1146]   Content-Disposition: attachment; filename=\\"test.bin\\"
[Mon Apr 15 09:03:33.444967 2013] [http:trace4] [pid 2576:tid 1260] http_filters.c(804): [client 127.0.0.1:1146]   Content-Length: 209715200
[Mon Apr 15 09:03:33.444967 2013] [http:trace4] [pid 2576:tid 1260] http_filters.c(804): [client 127.0.0.1:1146]   Keep-Alive: timeout=5, max=100
[Mon Apr 15 09:03:33.444967 2013] [http:trace4] [pid 2576:tid 1260] http_filters.c(804): [client 127.0.0.1:1146]   Connection: Keep-Alive
[Mon Apr 15 09:03:33.444967 2013] [http:trace4] [pid 2576:tid 1260] http_filters.c(804): [client 127.0.0.1:1146]   Content-Type: application/octet-stream
[Mon Apr 15 09:03:33.444967 2013] [core:trace6] [pid 2576:tid 1260] core_filters.c(523): [client 127.0.0.1:1146] core_output_filter: flushing because of THRESHOLD_MAX_BUFFER
 [2013-04-15 07:06 UTC] kontrollfreak at arcor dot de
-Status: Feedback +Status: Open
 
PHP Copyright © 2001-2020 The PHP Group
All rights reserved.
Last updated: Wed Nov 25 09:01:23 2020 UTC