Bug #60671 [Asn->Opn]: fread does not fail when operating on a write only stream
| From: | kalle@php.net | Date: | Tue, 24 Oct 2017 07:58:26 +0000 |
| Subject: | Bug #60671 [Asn->Opn]: fread does not fail when operating on a write only stream | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-212194@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=60671&edit=1
ID: 60671
Updated by: kalle@php.net
Reported by: james dot turner dot phpninja at gmail dot com
Summary: fread does not fail when operating on a write only
stream
-Status: Assigned
+Status: Open
Type: Bug
Package: Streams related
Operating System: Ubuntu 11.04
PHP Version: 5.3.8
-Assigned To: cataphract
+Assigned To:
Block user comment: N
Private report: N
Previous Comments:
------------------------------------------------------------------------
[2016-01-03 00:05:40] salsi at icosaedro dot it
Related To: Bug #60671
------------------------------------------------------------------------
[2016-01-03 00:05:39] salsi at icosaedro dot it
The problem here is more general, as there is no way to detect file access errors because, as
already stated, the ferror() function of the libc has no a corresponding implementation under PHP.
In my opinion, on an application language as PHP is, such a low level function should not exist and
instead should be fread() to return FALSE when it fails reading from a file because a I/O error of
any kind happened, and should emit E_WARNING with appropriate message. The same should apply to any
other file access function as well.
If it may be useful, i wrote this script that simulates a I/O error on Linux, and illustrates how
the access errors cannot be detected from PHP code:
<?php
// fread() fails to detect I/O error, bug #60671.
// Test code working on Linux only.
//
// Set a safe environment:
//
error_reporting(-1);
ini_set("track_errors", "1");
function my_error_handler($errno, $message /*, $filename, $lineno, $context */)
{
throw new ErrorException("$errno: $message");
}
set_error_handler("my_error_handler");
function main()
{
// Simulate I/O error in Linux (credits http://unix.stackexchange.com/a/6302):
// reading of the first 512-bytes block of /proc/self/mem causes EIO in libc.
// $ cat /proc/self/mem
// cat: /proc/self/mem: Input/output error
$r = fopen("/proc/self/mem", "r");
while( ! feof($r) ){
$s = fread($r, 100);
echo "read: "; var_dump($s);
}
fclose($r);
// Outcome: no errors whatsoever, only displays:
// read: string(0) ""
}
main();
------------------------------------------------------------------------
[2012-01-10 13:38:55] cataphract@php.net
All right, I'll give a bit more thought to this.
------------------------------------------------------------------------
[2012-01-08 21:45:18] phpmpan at mpan dot pl
You are right: no one should try to read from write-only stream. Also no one should try to divide by
0 and no one should pass something other than stream to
fread. But people do it all the
time and that's why errors, warnings, exceptions and status codes exist. Using an invalid type
of a stream is an error too and should be reported.
If returning FALSE from fread breaks something, than I agree:
fread bahaviour should not be changed. However a warning does not break anything, so it
can be emitted. Since php_stream stores fopen flags in mode,
I believe this can be done easily:
--------------- BEGIN DIFF ---------------
diff php5.3-201201041830/ext/standard/file.c php5.3-201201041830-modified/ext/standard/file.c
1893a1894,1898
>
> if (strpbrk(stream->mode, "+r") == NULL) { /* r or any + mode is fine */
> php_error_docref(NULL TSRMLS_CC, E_WARNING,
> "Reading from a write-only stream");
> }
---------------- END DIFF ----------------
After this modification some of ext/standard/tests/file/007* tests will fail, but this is expected.
I agree that this case is a feature request.
------------------------------------------------------------------------
[2012-01-08 09:29:07] james dot turner dot phpninja at gmail dot com
I feel I should say that just because the behaviour is analogous to the way the underlying C works
does not make it correct nor useful.
While I concur that one should not really attempt to read from a write-only stream, I DO feel that
any attempt to perform such an action should warrant an exception/warning/error of some sort. This
is currently not the case and as a result can lead to potential indefinite loops given recommended
usage in the PHP documentation.
Perhaps this should be a feature/change request?
------------------------------------------------------------------------
The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at
https://bugs.php.net/bug.php?id=60671
--
Edit this bug report at https://bugs.php.net/bug.php?id=60671&edit=1