diff options
author | Christoph M. Becker <cmbecker69@gmx.de> | 2019-08-20 16:04:14 +0200 |
---|---|---|
committer | Christoph M. Becker <cmbecker69@gmx.de> | 2019-08-20 16:04:14 +0200 |
commit | c03114e55c7b9367fc9be895fe0df01cd1b62cab (patch) | |
tree | e738260fd074bb5d3287fa4dec208c075a07875b | |
parent | ae923287cada2bb59877e806c8219b74f7d857d5 (diff) | |
download | php-git-c03114e55c7b9367fc9be895fe0df01cd1b62cab.tar.gz |
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.
-rw-r--r-- | NEWS | 1 | ||||
-rw-r--r-- | ext/standard/tests/file/bug78386.phpt | 14 | ||||
-rw-r--r-- | win32/ioutil.c | 15 |
3 files changed, 29 insertions, 1 deletions
@@ -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 diff --git a/ext/standard/tests/file/bug78386.phpt b/ext/standard/tests/file/bug78386.phpt new file mode 100644 index 0000000000..9118761aab --- /dev/null +++ b/ext/standard/tests/file/bug78386.phpt @@ -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" diff --git a/win32/ioutil.c b/win32/ioutil.c index 669876da38..f7db410dd2 100644 --- a/win32/ioutil.c +++ b/win32/ioutil.c @@ -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)); } |