diff options
-rw-r--r-- | NEWS | 1 | ||||
-rw-r--r-- | Zend/zend_virtual_cwd.c | 20 | ||||
-rw-r--r-- | ext/standard/tests/dir/bug78220.phpt | 16 |
3 files changed, 35 insertions, 2 deletions
@@ -3,6 +3,7 @@ PHP NEWS ?? ??? 2019, PHP 7.2.23 - Core: + . Fixed bug #78220 (Can't access OneDrive folder). (cmb, ab) . Fixed bug #78412 (Generator incorrectly reports non-releasable $this as GC child). (Nikita) diff --git a/Zend/zend_virtual_cwd.c b/Zend/zend_virtual_cwd.c index f9395f32a4..563e121b7e 100644 --- a/Zend/zend_virtual_cwd.c +++ b/Zend/zend_virtual_cwd.c @@ -91,6 +91,8 @@ cwd_state main_cwd_state; /* True global */ #include <unistd.h> #else #include <direct.h> +#include "zend_globals.h" +#include "zend_globals_macros.h" #endif #define CWD_STATE_COPY(d, s) \ @@ -855,6 +857,7 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i tmp = do_alloca(len+1, use_heap); memcpy(tmp, path, len+1); +retry: if(save && !(IS_UNC_PATH(path, len) && len >= 3 && path[2] != '?') && (dataw.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) @@ -895,7 +898,21 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i return -1; } if(!DeviceIoControl(hLink, FSCTL_GET_REPARSE_POINT, NULL, 0, pbuffer, MAXIMUM_REPARSE_DATA_BUFFER_SIZE, &retlength, NULL)) { + BY_HANDLE_FILE_INFORMATION fileInformation; + free_alloca(pbuffer, use_heap_large); + if ((dataw.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) && + (dataw.dwReserved0 & ~IO_REPARSE_TAG_CLOUD_MASK) == IO_REPARSE_TAG_CLOUD && + EG(windows_version_info).dwMajorVersion >= 10 && + EG(windows_version_info).dwMinorVersion == 0 && + EG(windows_version_info).dwBuildNumber >= 18362 && + GetFileInformationByHandle(hLink, &fileInformation) && + !(fileInformation.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) { + dataw.dwFileAttributes = fileInformation.dwFileAttributes; + CloseHandle(hLink); + (*ll)--; + goto retry; + } free_alloca(tmp, use_heap); CloseHandle(hLink); FREE_PATHW() @@ -975,8 +992,7 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i } else if (pbuffer->ReparseTag == IO_REPARSE_TAG_DEDUP || /* Starting with 1709. */ - (pbuffer->ReparseTag & IO_REPARSE_TAG_CLOUD_MASK) != 0 && 0x90001018L != pbuffer->ReparseTag || - IO_REPARSE_TAG_CLOUD == pbuffer->ReparseTag || + (pbuffer->ReparseTag & ~IO_REPARSE_TAG_CLOUD_MASK) == IO_REPARSE_TAG_CLOUD || IO_REPARSE_TAG_ONEDRIVE == pbuffer->ReparseTag) { isabsolute = 1; substitutename = malloc((len + 1) * sizeof(char)); diff --git a/ext/standard/tests/dir/bug78220.phpt b/ext/standard/tests/dir/bug78220.phpt new file mode 100644 index 0000000000..16daa0d716 --- /dev/null +++ b/ext/standard/tests/dir/bug78220.phpt @@ -0,0 +1,16 @@ +--TEST-- +Bug #78220 (Can't access OneDrive folder) +--SKIPIF-- +<?php +if (substr(PHP_OS, 0, 3) != 'WIN') die("skip this test is for Windows platforms only"); +?> +--FILE-- +<?php +$onedrive_dirs = array_unique([getenv('OneDrive'), getenv('OneDriveCommercial')]); +foreach ($onedrive_dirs as $dir) { + if ($dir && scandir($dir) === FALSE) { + echo "can't scan $dir\n"; + } +} +?> +--EXPECT-- |