Fix #78386: fstat mode has unexpected value on PHP 7.4

We must not assume that any file which is not a directory is a regular
file.  Therefore we employ `GetFileType()` in this case to properly
distinguish between character special, FIFO special and regular files.
This commit is contained in:
Christoph M. Becker 2019-08-20 16:04:14 +02:00
parent ae923287ca
commit c03114e55c
3 changed files with 29 additions and 1 deletions

1
NEWS
View file

@ -9,6 +9,7 @@ PHP NEWS
. Fixed bug #78406 (Broken file includes with user-defined stream filters).
(Nikita)
. Fixed bug #72530 (Use After Free in GC with Certain Destructors). (Nikita)
. Fixed bug #78386 (fstat mode has unexpected value on PHP 7.4). (cmb)
- Date:
. Fixed bug #78383 (Casting a DateTime to array no longer returns its

View file

@ -0,0 +1,14 @@
--TEST--
Bug #78386 (fstat mode has unexpected value on PHP 7.4)
--SKIPIF--
<?php
if (substr(PHP_OS, 0, 3) != 'WIN') die("skip this test is for Windows platforms only");
?>
--FILE--
<?php
$handle = popen('dir', 'r');
$stat = fstat($handle);
var_dump(decoct($stat['mode']));
?>
--EXPECT--
string(5) "10666"

View file

@ -942,7 +942,20 @@ static int php_win32_ioutil_fstat_int(HANDLE h, php_win32_ioutil_stat_t *buf, co
}
if ((data->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) == 0) {
buf->st_mode |= is_dir ? (S_IFDIR|S_IEXEC|(S_IEXEC>>3)|(S_IEXEC>>6)) : S_IFREG;
if (is_dir) {
buf->st_mode |= (S_IFDIR|S_IEXEC|(S_IEXEC>>3)|(S_IEXEC>>6));
} else {
switch (GetFileType(h)) {
case FILE_TYPE_CHAR:
buf->st_mode |= S_IFCHR;
break;
case FILE_TYPE_PIPE:
buf->st_mode |= S_IFIFO;
break;
default:
buf->st_mode |= S_IFREG;
}
}
buf->st_mode |= (data->dwFileAttributes & FILE_ATTRIBUTE_READONLY) ? (S_IREAD|(S_IREAD>>3)|(S_IREAD>>6)) : (S_IREAD|(S_IREAD>>3)|(S_IREAD>>6)|S_IWRITE|(S_IWRITE>>3)|(S_IWRITE>>6));
}