pajoye Mon, 14 Sep 2009 18:46:56 +0000 Revision: http://svn.php.net/viewvc?view=revision&revision=288339
Log: - Fix #48746, improve fix to support all possible cases (see latest comment in the report) Bug: http://bugs.php.net/48746 (Assigned) Unable to browse directories within Junction Points Changed paths: U php/php-src/branches/PHP_5_3/TSRM/tsrm_virtual_cwd.c U php/php-src/trunk/TSRM/tsrm_virtual_cwd.c Modified: php/php-src/branches/PHP_5_3/TSRM/tsrm_virtual_cwd.c =================================================================== --- php/php-src/branches/PHP_5_3/TSRM/tsrm_virtual_cwd.c 2009-09-14 18:12:51 UTC (rev 288338) +++ php/php-src/branches/PHP_5_3/TSRM/tsrm_virtual_cwd.c 2009-09-14 18:46:56 UTC (rev 288339) @@ -667,11 +667,14 @@ /* File is a reparse point. Get the target */ HANDLE hLink = NULL; REPARSE_DATA_BUFFER * pbuffer; - unsigned int retlength = 0, rname_off = 0; - int bufindex = 0, rname_len = 0, isabsolute = 0; + unsigned int retlength = 0; + int bufindex = 0, isabsolute = 0; wchar_t * reparsetarget; - WCHAR szVolumePathNames[MAX_PATH]; BOOL isVolume = FALSE; + char printname[MAX_PATH]; + char substitutename[MAX_PATH]; + int printname_len, substitutename_len; + int substitutename_off = 0; if(++(*ll) > LINK_MAX) { return -1; @@ -692,33 +695,61 @@ CloseHandle(hLink); if(pbuffer->ReparseTag == IO_REPARSE_TAG_SYMLINK) { - rname_len = pbuffer->SymbolicLinkReparseBuffer.PrintNameLength/2; - rname_off = pbuffer->SymbolicLinkReparseBuffer.PrintNameOffset/2; - if(rname_len <= 0) { - rname_len = pbuffer->SymbolicLinkReparseBuffer.SubstituteNameLength/2; - rname_off = pbuffer->SymbolicLinkReparseBuffer.SubstituteNameOffset/2; - } - reparsetarget = pbuffer->SymbolicLinkReparseBuffer.ReparseTarget; + printname_len = pbuffer->MountPointReparseBuffer.PrintNameLength / sizeof(WCHAR); isabsolute = (pbuffer->SymbolicLinkReparseBuffer.Flags == 0) ? 1 : 0; + if (!WideCharToMultiByte(CP_THREAD_ACP, 0, + reparsetarget + pbuffer->MountPointReparseBuffer.PrintNameOffset / sizeof(WCHAR), + printname_len + 1, + printname, MAX_PATH, NULL, NULL + )) { + tsrm_free_alloca(pbuffer, use_heap_large); + return -1; + }; + printname_len = pbuffer->MountPointReparseBuffer.PrintNameLength / sizeof(WCHAR); + printname[printname_len] = 0; + + substitutename_len = pbuffer->MountPointReparseBuffer.SubstituteNameLength / sizeof(WCHAR); + if (!WideCharToMultiByte(CP_THREAD_ACP, 0, + reparsetarget + pbuffer->MountPointReparseBuffer.SubstituteNameOffset / sizeof(WCHAR), + substitutename_len + 1, + substitutename, MAX_PATH, NULL, NULL + )) { + tsrm_free_alloca(pbuffer, use_heap_large); + return -1; + }; + substitutename[substitutename_len] = 0; } else if(pbuffer->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT) { - rname_len = pbuffer->MountPointReparseBuffer.PrintNameLength/2; - rname_off = pbuffer->MountPointReparseBuffer.PrintNameOffset/2; - if(rname_len <= 0) { - rname_len = pbuffer->MountPointReparseBuffer.SubstituteNameLength/2; - rname_off = pbuffer->MountPointReparseBuffer.SubstituteNameOffset/2; - } + isabsolute = 1; + reparsetarget = pbuffer->MountPointReparseBuffer.ReparseTarget; + printname_len = pbuffer->MountPointReparseBuffer.PrintNameLength / sizeof(WCHAR); + if (!WideCharToMultiByte(CP_THREAD_ACP, 0, + reparsetarget + pbuffer->MountPointReparseBuffer.PrintNameOffset / sizeof(WCHAR), + printname_len + 1, + printname, MAX_PATH, NULL, NULL + )) { + tsrm_free_alloca(pbuffer, use_heap_large); + return -1; + }; + printname[pbuffer->MountPointReparseBuffer.PrintNameLength / sizeof(WCHAR)] = 0; - reparsetarget = pbuffer->MountPointReparseBuffer.ReparseTarget; - isabsolute = 1; - } - else { + substitutename_len = pbuffer->MountPointReparseBuffer.SubstituteNameLength / sizeof(WCHAR); + if (!WideCharToMultiByte(CP_THREAD_ACP, 0, + reparsetarget + pbuffer->MountPointReparseBuffer.SubstituteNameOffset / sizeof(WCHAR), + substitutename_len + 1, + substitutename, MAX_PATH, NULL, NULL + )) { + tsrm_free_alloca(pbuffer, use_heap_large); + return -1; + }; + substitutename[substitutename_len] = 0; + } else { tsrm_free_alloca(pbuffer, use_heap_large); return -1; } - if(isabsolute && rname_len > 4) { + if(isabsolute && substitutename_len > 4) { /* Do not resolve volumes (for now). A mounted point can target a volume without a drive, it is not certain that all IO functions we use in php and its deps support @@ -726,21 +757,22 @@ d:\test\mnt\foo \\?\Volume{62d1c3f8-83b9-11de-b108-806e6f6e6963}\foo */ - if (wcsncmp(reparsetarget, L"\\??\\Volume{",11) == 0 - || wcsncmp(reparsetarget, L"\\\\?\\Volume{",11) == 0) { + if (strncmp(substitutename, "\\??\\Volume{",11) == 0 + || strncmp(substitutename, "\\\\?\\Volume{",11) == 0) { isVolume = TRUE; + substitutename_off = 0; } else /* do not use the \??\ and \\?\ prefix*/ - if (wcsncmp(reparsetarget, L"\\??\\", 4) == 0 - || wcsncmp(reparsetarget, L"\\\\?\\", 4) == 0) { - rname_off += 4; - rname_len -= 4; + if (strncmp(substitutename, "\\??\\", 4) == 0 + || strncmp(substitutename, "\\\\?\\", 4) == 0) { + substitutename_off = 4; } } + if (!isVolume) { - /* Convert wide string to narrow string */ - for(bufindex = 0; bufindex < rname_len; bufindex++) { - *(path + bufindex) = (char)(reparsetarget[rname_off + bufindex]); + char * tmp = substitutename + substitutename_off; + for(bufindex = 0; bufindex < (substitutename_len - substitutename_off); bufindex++) { + *(path + bufindex) = *(tmp + bufindex); } *(path + bufindex) = 0; @@ -748,6 +780,13 @@ } else { j = len; } + + +#if VIRTUAL_CWD_DEBUG + fprintf(stderr, "reparse: print: %s ", printname); + fprintf(stderr, "sub: %s ", substitutename); + fprintf(stderr, "resolved: %s ", path); +#endif tsrm_free_alloca(pbuffer, use_heap_large); if(isabsolute == 1) { Modified: php/php-src/trunk/TSRM/tsrm_virtual_cwd.c =================================================================== --- php/php-src/trunk/TSRM/tsrm_virtual_cwd.c 2009-09-14 18:12:51 UTC (rev 288338) +++ php/php-src/trunk/TSRM/tsrm_virtual_cwd.c 2009-09-14 18:46:56 UTC (rev 288339) @@ -905,6 +905,7 @@ time_t t; int ret; int add_slash; + void *tmp; TSRMLS_FETCH(); if (path_length == 0 || path_length >= MAXPATHLEN-1) { @@ -1049,7 +1050,16 @@ CWD_STATE_COPY(&old_state, state); state->cwd_length = path_length; - state->cwd = (char *) realloc(state->cwd, state->cwd_length+1); + + tmp = realloc(state->cwd, state->cwd_length+1); + if (tmp == NULL) { +#if VIRTUAL_CWD_DEBUG + fprintf (stderr, "Out of memory\n"); +#endif + return 1; + } + state->cwd = (char *) tmp; + memcpy(state->cwd, resolved_path, state->cwd_length+1); if (verify_path(state)) { CWD_STATE_FREE(state); @@ -1061,7 +1071,15 @@ } } else { state->cwd_length = path_length; - state->cwd = (char *) realloc(state->cwd, state->cwd_length+1); + tmp = realloc(state->cwd, state->cwd_length+1); + if (tmp == NULL) { +#if VIRTUAL_CWD_DEBUG + fprintf (stderr, "Out of memory\n"); +#endif + return 1; + } + state->cwd = (char *) tmp; + memcpy(state->cwd, resolved_path, state->cwd_length+1); ret = 0; }
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php