Package home | Report new bug | New search | Development Roadmap Status: Open | Feedback | All | Closed Since Version 1.4.1

Bug #4835 ReadLine causes memory exhaustion
Submitted: 2005-07-14 20:42 UTC
From: chris dot stone at gmail dot com Assigned: mike
Status: Closed Package: File
PHP Version: 5.0.4 OS: RHEL4
Roadmaps: (Not assigned)    
Subscription  


 [2005-07-14 20:42 UTC] chris dot stone at gmail dot com
Description: ------------ File::readLine() doesn't work. Reproduce code: --------------- $foo = File::readLine('bar'); Expected result: ---------------- it works? Actual result: -------------- it doesn't work

Comments

 [2005-07-18 08:55 UTC] mike
Not enough information was provided for us to be able to handle this bug. Please re-read the instructions at http://bugs.php.net/how-to-report.php If you can provide more information, feel free to add it to this bug and change the status back to "Open". Thank you for your interest in PEAR.
 [2005-07-20 07:35 UTC] chris dot stone at gmail dot com
From bug 4865 (hope this is enough info) Description: ------------ Using File::readLine with PHP5 is totally broken, I don't know how else to describe it. When I load the test page below absolutely nothing happens at all. No errors, no page refresh, nothing. It's like PHP is breaking or something?? Reproduce code: --------------- <?php require_once 'File.php'; var_dump(File::readLine('foo.txt')); ?> foo.txt contains: This is a file test. With two lines in it. Expected result: ---------------- var_dump of "This is a file test." Actual result: -------------- Complete breakage, page doesn't even start, for example, if you have another page already loaded and try to load file.php, the old page just remains on the screen.
 [2005-07-20 08:38 UTC] mike
What package version are you using? Please enable error_reporting and investigate your logs. I cannot reproduce this failure. Thanks
 [2005-07-20 09:27 UTC] chris dot stone at gmail dot com
I modified my example program to this: <?php error_reporting(E_ALL); ini_set('display_errors', 'On'); require 'File.php'; var_dump(File::readLine('foo.txt')); ?> And as I said, absolutely nothing happens. No headers are sent, no errors are shown, no page is loaded, no output is printed. The previous page I have loaded does not even go away. It basically just dies and does nothing. Is there a file where errors are logged?
 [2005-07-20 09:28 UTC] chris dot stone at gmail dot com
Oh forgot to mention version info: $ pear info file About File-1.2.0
 [2005-07-20 09:38 UTC] chris dot stone at gmail dot com
If I try to browse to the example.php file from a new window (no previous page loaded), I do get some headers on the output: <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head><title></title></head><body></body></html> but that is all it prints.
 [2005-07-20 09:47 UTC] chris dot stone at gmail dot com
I'm not sure if this will help you, but I also tried it on my local server at home using Fedora Core 4 which also uses PHP 5.0.4 and I get the same results. You can see the results at: http://xulchris.dyndns.org/example.php Please let me know if you need me to modify the example script at all. If I change readLine to readAll, the script runs correctly.
 [2005-07-20 10:01 UTC] mike
Apaches error log would be the last frontier. There "should" be some lines noting segfaults (SIGSEGV) regarding your explanations. If that's the case, you need to get a backtrace. Thanks.
 [2005-07-20 10:12 UTC] chris dot stone at gmail dot com
Apache is giving me an error message: [client 209.78.16.118] PHP Fatal error: Allowed memory size of 8388608 bytes ex hausted (tried to allocate 8192001 bytes) in /usr/share/pear/File.php on line 32 6 Allowed memory size of 8388608 bytes exhausted (tried to allocate 256 bytes) hope this helps.
 [2005-07-20 10:21 UTC] chris dot stone at gmail dot com
The following patch fixes the problem: --- File.php.orig 2005-07-20 03:20:15.000000000 -0700 +++ File.php 2005-07-20 03:20:34.000000000 -0700 @@ -323,7 +323,7 @@ return false; } - return rtrim(fgets($fp, FILE_MAX_LINE_READSIZE), "\r\n"); + return rtrim(fgets($fp, FILE_DEFAULT_READSIZE), "\r\n"); } /**
 [2005-07-20 12:03 UTC] mike
Try to define FILE_MAX_LINE_READSIZE to something you expect your longest line will be, e.g. 4096: define('FILE_MAX_LINE_READSIZE', 4096); require_once 'File.php';
 [2005-07-20 15:31 UTC] chris dot stone at gmail dot com
Yes, this will work, but it seems that this is a work-around to the real problem. It seems as if PHP is not detecting EOL or EOF characters. I've reviewed the code in File.php, and nothing seems incorrect. The length parameter to fgets should not allocate 8M of RAM on a simple two line file thats < 1k. fgets() is supposed to return the smallest of string to EOL, EOF or length. I think I should try to recreate this problem using standard PHP calls such as fopen and fgets and file a bug report with PHP or RedHat. Please let me know if you have any insight on what might be going wrong. Thanks for the help, I'm glad we atleast have a working work-around to the problem! :)
 [2005-07-21 01:56 UTC] chris dot stone at gmail dot com
<?php define('FILE_MAX_LINE_READSIZE', 8192000, true); define('FILE_MODE_READ', 'rb', true); $fp = @fopen('foo.txt', FILE_MODE_READ); var_dump(rtrim(fgets($fp, FILE_MAX_LINE_READSIZE), "\r\n")); ?> Okay I tried using standard PHP calls (see above), and it works just fine when I do it this way. For some reason, the fgets() call is not working under the File class. :/ Any ideas?
 [2005-07-21 02:57 UTC] chris dot stone at gmail dot com
<?php require 'PEAR.php'; error_reporting(E_ALL); ini_set('display_errors', 'On'); define('FILE_MAX_LINE_READSIZE', 8192000, true); define('FILE_MODE_READ', 'rb', true); class MyFile { function myReadLine($filename, $lock = false) { $fp = @fopen($filename, FILE_MODE_READ); var_dump(rtrim(fgets($fp, FILE_MAX_LINE_READSIZE), "\r\n")); } } MyFile::MyReadLine('foo.txt'); ?> Okay, I've reduced the error down to the simplest code possible to reproduce the error. This code will cause the following error: Fatal error: Allowed memory size of 8388608 bytes exhausted (tried to allocate 8192 bytes) in /var/www/html/example2.php on line 16 However, if I comment out the require 'PEAR.php'; line, the code will work!
 [2005-07-21 07:53 UTC] mike
This bug has been fixed in CVS. In case this was a documentation problem, the fix will show up at the end of next Sunday (CET) on pear.php.net. In case this was a pear.php.net website problem, the change will show up on the website in short time. Thank you for the report, and for helping us make PEAR better. Actually it boils down to be my fault, sorry. I introduced FILE_MAX_LINE_READ_SIZE in 1.1.0RC1 but was *not* aware that the PHP stream will try to pre-allocate the supplied length amounts of bytes.