Bug #60671 [Opn->Csd]: fread does not fail when operating on a write only stream

From: Date: Wed, 28 Jul 2021 08:37:05 +0000
Subject: Bug #60671 [Opn->Csd]: 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-235423@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: cmb@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: Open +Status: Closed Type: Bug Package: Streams related Operating System: Ubuntu 11.04 PHP Version: 5.3.8 -Assigned To: +Assigned To: cmb Block user comment: N Private report: N New Comment: This issue is resolved for all actively supported PHP versions[1]. fread() returns false for write only streams. [1] <https://www.php.net/supported-versions.php> 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

« previous php.bugs (#235423) next »