pajoye                                   Mon, 19 Oct 2009 23:43:31 +0000

Revision: http://svn.php.net/viewvc?view=revision&revision=289782

Log:
- MF53: 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/trunk/TSRM/tsrm_virtual_cwd.c

Modified: php/php-src/trunk/TSRM/tsrm_virtual_cwd.c
===================================================================
--- php/php-src/trunk/TSRM/tsrm_virtual_cwd.c   2009-10-19 23:41:14 UTC (rev 
289781)
+++ php/php-src/trunk/TSRM/tsrm_virtual_cwd.c   2009-10-19 23:43:31 UTC (rev 
289782)
@@ -706,10 +706,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;
                        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;
@@ -730,33 +734,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
@@ -764,21 +796,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;
@@ -786,6 +819,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) {

-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to