summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS1
-rw-r--r--Zend/zend_virtual_cwd.c20
-rw-r--r--ext/standard/tests/dir/bug78220.phpt16
3 files changed, 35 insertions, 2 deletions
diff --git a/NEWS b/NEWS
index 8ad64104fb..bcec73d1a7 100644
--- a/NEWS
+++ b/NEWS
@@ -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--