PEAR is discontinued

This is a static archive preserving historical releases and metadata. No new packages or updates will be published. For updates to existing packages, or to publish new packages, please use Composer and Packagist.

Home » Networking » Net_Socket » Bug #7692

readLine exits silently on error

Details

Submitted2006-05-22 10:58 UTC
Fromjason dot e dot stewart at gmail dot com
Assignedchagenbu
StatusClosed
PackageNet_Socket
PHP Version5.0.2
OSWindows NT
Roadmaps(Not assigned)

Comments

[2006-05-22 10:58 UTC] jason dot e dot stewart at gmail dot com

Description:
------------
because readLine() calls @fgets(...) any error will cause the function to exit silently with no trace of what happened.

This happens if max_execution_time is set low and there is a long process at the other end of the socket. This caused a really dificult to trace error. Because the error was a fatal error my custom error handler didn't even catch it...

Why is @fgets() called and not just fgets()??

[2006-05-22 11:01 UTC] jason dot e dot stewart at gmail dot com

this bug is linked to BUG# 7691

[2006-05-22 18:05 UTC] chagenbu at php dot net

Well, not everyone is using a custom error handler that would catch warnings. For some scripts, if a warning was generated (say a request times out), they might just want to get back a return false and redirect somewhere else - but oops, headers have already been sent.

Since fgets() will only ever generate a warning, not a fatal error (by itself), we silence it.

[2006-05-23 05:24 UTC] jason dot e dot stewart at gmail dot com

Maybe I was unclear.

When the socket read exceeds the max_execution_time setting it causes a FATAL ERROR - this error is discarded because of @fgets():

PHP Fatal Error: maximum execution time of 30 secs exceeded in c:\Program Files\php5\PEAR\Net\Socket.php on line 448

My script exits completely because of this error - and nothing I do can trap it - so I am clueless what is happening.

I was only able to get the above text by removing the '@' operator.

Discarding warnings is one thing - but discarding errors is a righteous pain in the a**...

[2006-05-26 18:18 UTC] chagenbu at php dot net

Okay, I did misunderstand you. I have very mixed feelings about this. On the one hand, silencing a fatal error is never a good thing - completely with you on that. However there are probably a ton of applications and packages out there that expect Net_Socket not to generate warnings, thus potentially breaking header() calls, or generally mucking things up.

I'm not sure what the answer is here. I wonder what would happen if we called ob_start() before the fgets/fread calls in question, assigned the data instead of returning it, then ob_end_clean(), finally return the result. That'd effectively silence warnings still; the question is if it'd silence the fatal error. Would you be willing to test this?

[2006-05-27 17:02 UTC] jason dot e dot stewart at gmail dot com

yes, I still have my application set up on the test server. It would be easy to test. Send my a patch and I'll try it out.

[2006-05-29 01:44 UTC] chagenbu at php dot net

Here you are:

Index: Socket.php
===================================================================
RCS file: /repository/pear/Net_Socket/Socket.php,v
retrieving revision 1.25
diff -u -r1.25 Socket.php
--- Socket.php 15 Nov 2005 03:48:06 -0000 1.25
+++ Socket.php 29 May 2006 01:44:26 -0000
@@ -441,14 +441,17 @@
return $this->raiseError('not connected');
}

+ ob_start();
$line = '';
$timeout = time() + $this->timeout;
while (!feof($this->fp) && (!$this->timeout || time() < $timeout)) {
- $line .= @fgets($this->fp, $this->lineLength);
+ $line .= fgets($this->fp, $this->lineLength);
if (substr($line, -1) == "\n") {
+ ob_end_clean();
return rtrim($line, "\r\n");
}
}
+ ob_end_clean();
return $line;
}

[2006-06-02 09:14 UTC] jason dot e dot stewart at gmail dot com

yup, that does the trick for me.

without the @fgets(), the error gets propagated.

Thanks.