diff --git a/Zend/tests/require_directory.phpt b/Zend/tests/require_directory.phpt deleted file mode 100644 index c8b4b6a6382..00000000000 --- a/Zend/tests/require_directory.phpt +++ /dev/null @@ -1,21 +0,0 @@ ---TEST-- -Including a directory generates an error ---SKIPIF-- - ---FILE-- - ---EXPECTF-- -Notice: require(): Read of %d bytes failed with errno=21 Is a directory in %s on line %d - -Fatal error: Uncaught Error: Failed opening required '%s' (include_path='.:') in %s:%d -Stack trace: -#0 {main} - thrown in %s on line %d diff --git a/Zend/tests/require_directory_windows.phpt b/Zend/tests/require_directory_windows.phpt deleted file mode 100644 index d8b68c2064e..00000000000 --- a/Zend/tests/require_directory_windows.phpt +++ /dev/null @@ -1,21 +0,0 @@ ---TEST-- -Including a directory generates an error (Windows variant) ---SKIPIF-- - ---FILE-- - ---EXPECTF-- -Warning: require(%s): Failed to open stream: Permission denied in %s on line %d - -Fatal error: Uncaught Error: Failed opening required '%s' (include_path='%s') in %s:%d -Stack trace: -#0 {main} - thrown in %s on line %d diff --git a/ext/standard/tests/file/bug35740.phpt b/ext/standard/tests/file/bug35740.phpt index d06b53be06e..29ab0248d8d 100644 --- a/ext/standard/tests/file/bug35740.phpt +++ b/ext/standard/tests/file/bug35740.phpt @@ -1,9 +1,5 @@ --TEST-- Bug #35740 (memory leak when including a directory) ---SKIPIF-- - --FILE-- --EXPECTF-- -Notice: include(): Read of %s bytes failed with errno=21 Is a directory in %s on line %d +Warning: include(%s): Failed to open stream: %s in %s on line %d Warning: include(): Failed opening '%s' for inclusion (include_path='%s') in %s on line %d Done diff --git a/main/streams/plain_wrapper.c b/main/streams/plain_wrapper.c index a0471a8b921..a8fd70b8d6a 100644 --- a/main/streams/plain_wrapper.c +++ b/main/streams/plain_wrapper.c @@ -135,6 +135,7 @@ typedef struct { unsigned is_pipe:1; /* stream is an actual pipe, currently Windows only*/ unsigned cached_fstat:1; /* sb is valid */ unsigned is_pipe_blocking:1; /* allow blocking read() on pipes, currently Windows only */ + unsigned no_forced_fstat:1; /* Use fstat cache even if forced */ unsigned is_seekable:1; /* don't try and seek, if not set */ unsigned _reserved:26; @@ -160,7 +161,7 @@ typedef struct { static int do_fstat(php_stdio_stream_data *d, int force) { - if (!d->cached_fstat || force) { + if (!d->cached_fstat || (force && !d->no_forced_fstat)) { int fd; int r; @@ -1187,7 +1188,30 @@ PHPAPI php_stream *_php_stream_fopen(const char *filename, const char *mode, zen efree(persistent_id); } + /* WIN32 always set ISREG flag */ #ifndef PHP_WIN32 + /* sanity checks for include/require. + * We check these after opening the stream, so that we save + * on fstat() syscalls */ + if (options & STREAM_OPEN_FOR_INCLUDE) { + php_stdio_stream_data *self = (php_stdio_stream_data*)ret->abstract; + int r; + + r = do_fstat(self, 0); + if ((r == 0 && !S_ISREG(self->sb.st_mode))) { + if (opened_path) { + zend_string_release_ex(*opened_path, 0); + *opened_path = NULL; + } + php_stream_close(ret); + return NULL; + } + + /* Make sure the fstat result is reused when we later try to get the + * file size. */ + self->no_forced_fstat = 1; + } + if (options & STREAM_USE_BLOCKING_PIPE) { php_stdio_stream_data *self = (php_stdio_stream_data*)ret->abstract; self->is_pipe_blocking = 1;