Skip to content

Commit cb9af8d

Browse files
committed
Revert "Remove include "sanity check" to get better error (#19650)"
This reverts commit ca4a841. We like the error message change, but not the downgrade to notice at this time in the release cycle. @bukka will come back around
1 parent ca4a841 commit cb9af8d

File tree

4 files changed

+26
-48
lines changed

4 files changed

+26
-48
lines changed

Zend/tests/require_directory.phpt

Lines changed: 0 additions & 21 deletions
This file was deleted.

Zend/tests/require_directory_windows.phpt

Lines changed: 0 additions & 21 deletions
This file was deleted.

ext/standard/tests/file/bug35740.phpt

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
11
--TEST--
22
Bug #35740 (memory leak when including a directory)
3-
--SKIPIF--
4-
<?php
5-
if (PHP_OS_FAMILY === 'Windows') die("skip Not for Windows");
6-
?>
73
--FILE--
84
<?php
95

@@ -12,7 +8,7 @@ include (__DIR__);
128
echo "Done\n";
139
?>
1410
--EXPECTF--
15-
Notice: include(): Read of %s bytes failed with errno=21 Is a directory in %s on line %d
11+
Warning: include(%s): Failed to open stream: %s in %s on line %d
1612

1713
Warning: include(): Failed opening '%s' for inclusion (include_path='%s') in %s on line %d
1814
Done

main/streams/plain_wrapper.c

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ typedef struct {
135135
unsigned is_pipe:1; /* stream is an actual pipe, currently Windows only*/
136136
unsigned cached_fstat:1; /* sb is valid */
137137
unsigned is_pipe_blocking:1; /* allow blocking read() on pipes, currently Windows only */
138+
unsigned no_forced_fstat:1; /* Use fstat cache even if forced */
138139
unsigned is_seekable:1; /* don't try and seek, if not set */
139140
unsigned _reserved:26;
140141

@@ -160,7 +161,7 @@ typedef struct {
160161

161162
static int do_fstat(php_stdio_stream_data *d, int force)
162163
{
163-
if (!d->cached_fstat || force) {
164+
if (!d->cached_fstat || (force && !d->no_forced_fstat)) {
164165
int fd;
165166
int r;
166167

@@ -1187,7 +1188,30 @@ PHPAPI php_stream *_php_stream_fopen(const char *filename, const char *mode, zen
11871188
efree(persistent_id);
11881189
}
11891190

1191+
/* WIN32 always set ISREG flag */
11901192
#ifndef PHP_WIN32
1193+
/* sanity checks for include/require.
1194+
* We check these after opening the stream, so that we save
1195+
* on fstat() syscalls */
1196+
if (options & STREAM_OPEN_FOR_INCLUDE) {
1197+
php_stdio_stream_data *self = (php_stdio_stream_data*)ret->abstract;
1198+
int r;
1199+
1200+
r = do_fstat(self, 0);
1201+
if ((r == 0 && !S_ISREG(self->sb.st_mode))) {
1202+
if (opened_path) {
1203+
zend_string_release_ex(*opened_path, 0);
1204+
*opened_path = NULL;
1205+
}
1206+
php_stream_close(ret);
1207+
return NULL;
1208+
}
1209+
1210+
/* Make sure the fstat result is reused when we later try to get the
1211+
* file size. */
1212+
self->no_forced_fstat = 1;
1213+
}
1214+
11911215
if (options & STREAM_USE_BLOCKING_PIPE) {
11921216
php_stdio_stream_data *self = (php_stdio_stream_data*)ret->abstract;
11931217
self->is_pipe_blocking = 1;

0 commit comments

Comments
 (0)