Bug->Req #69163 [Opn]: fopen(__DIR__, 'r') succeeds

From: Date: Wed, 12 Oct 2016 16:04:56 +0000
Subject: Bug->Req #69163 [Opn]: fopen(__DIR__, 'r') succeeds
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-204642@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=69163&edit=1 ID: 69163 Updated by: cmb@php.net Reported by: salsi at icosaedro dot it Summary: fopen(__DIR__, 'r') succeeds Status: Open -Type: Bug +Type: Feature/Change Request Package: Streams related Operating System: Linux PHP Version: Irrelevant Block user comment: N Private report: N New Comment: > Changed "Bug Type" from "Bug" to "Feature/Change request", > […] … and after previewing the comment, the bug tracker did reset to "bug" again – annoying bug. Previous Comments: ------------------------------------------------------------------------ [2015-03-05 09:25:14] salsi at icosaedro dot it Currently the libc fopen() function under Linux (and probably under any Unix-like OS) succeeds by opening a directory for reading, although nothing can be read and the EOF condition is immediately set. This is a legacy, very old behavior of the unices a modern application language as PHP is should not comply with anymore. Under Windows the same attempt immediately fails. My proposal is to make the PHP fopen() function behave in more consistent, cross-OS uniform and safer way by rejecting such an attempt atomically from inside PHP itself using a C code similar to this one, that detects the actual type of the opened file: FILE * f; struct stat fileinfo; //f = fopen(__FILE__, "r"); // works f = fopen("/", "r"); // --> displays "Ia a directory (PHP specific restriction)” //f = fopen("/root", "r"); // displays "Permission denied" //f = fopen("/dev/sda5", "r"); // displays "Permission denied" if( f == NULL ){ printf("%s\n", strerror(errno)); return 1; } if( fstat(fileno(f), &fileinfo) < 0 ){ printf("%s\n", strerror(errno)); return 1; } if( S_ISDIR(fileinfo.st_mode) ){ printf("Ia a directory (PHP specific restriction)"); return 1; } // OK In this way the manual page becomes simpler by removing ambiguous warnings and suggestions nobody applies anyway (never seen is_dir() after fopen() in a PHP program). Opening a directory for writing already gives error, so there is nothing to fix here: $f = fopen("/", "w"); –-> E_WARNING: fopen(/): failed to open stream: Is a directory Changed "Bug Type" from "Bug" to "Feature/Change request", which seems more appropriate. ------------------------------------------------------------------------ [2015-03-04 01:05:00] danack@php.net "A Linux system, just like UNIX, makes no difference between a file and a directory, since a directory is just a file containing names of other files." From the manual: Note: This function may also succeed when filename is a directory. If you are unsure whether filename is a file or a directory, you may need to use the is_dir() function before calling fopen(). Are you sure this actually should be treated as a bug? ------------------------------------------------------------------------ [2015-03-02 20:22:46] salsi at icosaedro dot it ERRATA/CORRIGE. In my test script, the line $f = fopen(__FILE__, 'r'); should contain a directory, for example: $f = fopen(__DIR__, 'r'); $f = fopen('.', 'r'); $f = fopen('..', 'r'); Thanks to Richard Gray for signaling this bug in my report. ADDENDUM. Under Windows Vista fopen() fails on a directory, as it should. ------------------------------------------------------------------------ [2015-03-02 19:16:32] salsi at icosaedro dot it Description: ------------ On Linux, opening a directory succeeds; subsequent reads always returns string("") and feof() is true, no warnings. Test script: --------------- <?php error_reporting(PHP_INT_MAX); $f = fopen(__FILE__, 'r'); var_dump($f); for($i=0; $i<3; $i++){ echo "feof is "; var_dump(feof($f)); echo "fread returns "; var_dump(fread($f, 10)); } Actual output: ---------------------------------- resource(5) of type (stream) feof is bool(false) fread returns string(10) "<?php erro" feof is bool(false) fread returns string(10) "r_reportin" feof is bool(false) fread returns string(10) "g(PHP_INT_" Expected result: ---------------- Expected output: ----------------------------------- E_WARNING: cannot open directory boolean(false) ... ------------------------------------------------------------------------ -- Edit this bug report at https://bugs.php.net/bug.php?id=69163&edit=1

« previous php.bugs (#204642) next »