diff options
Diffstat (limited to 'Zend')
-rw-r--r-- | Zend/zend_virtual_cwd.c | 20 |
1 files changed, 18 insertions, 2 deletions
diff --git a/Zend/zend_virtual_cwd.c b/Zend/zend_virtual_cwd.c index 8f8514ba23..177c66ed7f 100644 --- a/Zend/zend_virtual_cwd.c +++ b/Zend/zend_virtual_cwd.c @@ -93,6 +93,8 @@ static 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) \ @@ -608,6 +610,7 @@ static size_t tsrm_realpath_r(char *path, size_t start, size_t len, int *ll, tim 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) @@ -655,7 +658,21 @@ static size_t tsrm_realpath_r(char *path, size_t start, size_t len, int *ll, tim return (size_t)-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() @@ -735,8 +752,7 @@ static size_t tsrm_realpath_r(char *path, size_t start, size_t len, int *ll, tim } 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)); |