Andrew Eikum : shell32: Fix an off-by-one error that causes an infinite loop.

Alexandre Julliard julliard at winehq.org
Thu Nov 18 11:09:28 CST 2010


Module: wine
Branch: master
Commit: 2f05b5a6d981d54f272d193ea0bcd3a72144c88d
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=2f05b5a6d981d54f272d193ea0bcd3a72144c88d

Author: Andrew Eikum <aeikum at codeweavers.com>
Date:   Wed Nov 17 11:56:13 2010 -0600

shell32: Fix an off-by-one error that causes an infinite loop.

---

 dlls/shell32/shfldr_unixfs.c   |   14 +++++++++--
 dlls/shell32/tests/shlfolder.c |   47 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 58 insertions(+), 3 deletions(-)

diff --git a/dlls/shell32/shfldr_unixfs.c b/dlls/shell32/shfldr_unixfs.c
index 14bf900..628ab87 100644
--- a/dlls/shell32/shfldr_unixfs.c
+++ b/dlls/shell32/shfldr_unixfs.c
@@ -390,15 +390,23 @@ static BOOL UNIXFS_get_unix_path(LPCWSTR pszDosPath, char *pszCanonicalPath)
     /* Append the part relative to the drive symbolic link target. */
     lstrcpyW(dospath, pszDosPath);
     dospath_end = dospath + lstrlenW(dospath);
+    /* search for the most valid UNIX path possible, then append missing
+     * path parts */
     while(!(pszUnixPath = wine_get_unix_file_name(dospath))){
-        if(has_failed)
+        if(has_failed){
             *dospath_end = '/';
-        else
+            --dospath_end;
+        }else
             has_failed = 1;
-        while(*dospath_end != '\\' && *dospath_end != '/')
+        while(*dospath_end != '\\' && *dospath_end != '/'){
             --dospath_end;
+            if(dospath_end < dospath)
+                break;
+        }
         *dospath_end = '\0';
     }
+    if(dospath_end < dospath)
+        return FALSE;
     strcat(szPath, pszUnixPath + cDriveSymlinkLen);
     HeapFree(GetProcessHeap(), 0, pszUnixPath);
 
diff --git a/dlls/shell32/tests/shlfolder.c b/dlls/shell32/tests/shlfolder.c
index 31ef752..ad52a72 100644
--- a/dlls/shell32/tests/shlfolder.c
+++ b/dlls/shell32/tests/shlfolder.c
@@ -4062,6 +4062,7 @@ static void test_ParseDisplayNamePBC(void)
         {'F','i','l','e',' ','S','y','s','t','e','m',' ','B','i','n','d',' ','D','a','t','a',0};
     WCHAR adirW[] = {'C',':','\\','f','s','b','d','d','i','r',0};
     WCHAR afileW[] = {'C',':','\\','f','s','b','d','d','i','r','\\','f','i','l','e','.','t','x','t',0};
+    WCHAR afile2W[] = {'C',':','\\','f','s','b','d','d','i','r','\\','s','\\','f','i','l','e','.','t','x','t',0};
     const HRESULT exp_err = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
 
     IShellFolder *psf;
@@ -4091,6 +4092,9 @@ static void test_ParseDisplayNamePBC(void)
     hres = IShellFolder_ParseDisplayName(psf, NULL, NULL, afileW, NULL, &pidl, NULL);
     ok(hres == exp_err || broken(hres == E_FAIL) /* NT4 */,
             "ParseDisplayName failed with wrong error: 0x%08x\n", hres);
+    hres = IShellFolder_ParseDisplayName(psf, NULL, NULL, afile2W, NULL, &pidl, NULL);
+    ok(hres == exp_err || broken(hres == E_FAIL) /* NT4 */,
+            "ParseDisplayName failed with wrong error: 0x%08x\n", hres);
 
     /* fails on unknown dir with IBindCtx with no IFileSystemBindData */
     hres = CreateBindCtx(0, &pbc);
@@ -4102,6 +4106,9 @@ static void test_ParseDisplayNamePBC(void)
     hres = IShellFolder_ParseDisplayName(psf, NULL, pbc, afileW, NULL, &pidl, NULL);
     ok(hres == exp_err || broken(hres == E_FAIL) /* NT4 */,
             "ParseDisplayName failed with wrong error: 0x%08x\n", hres);
+    hres = IShellFolder_ParseDisplayName(psf, NULL, pbc, afile2W, NULL, &pidl, NULL);
+    ok(hres == exp_err || broken(hres == E_FAIL) /* NT4 */,
+            "ParseDisplayName failed with wrong error: 0x%08x\n", hres);
 
     /* unknown dir with IBindCtx with IFileSystemBindData */
     hres = IBindCtx_RegisterObjectParam(pbc, wFileSystemBindData, (IUnknown*)&fsbd);
@@ -4126,6 +4133,14 @@ static void test_ParseDisplayNamePBC(void)
         ILFree(pidl);
     }
 
+    hres = IShellFolder_ParseDisplayName(psf, NULL, pbc, afile2W, NULL, &pidl, NULL);
+    ok(hres == S_OK || broken(hres == E_FAIL) /* NT4 */,
+            "ParseDisplayName failed: 0x%08x\n", hres);
+    if(SUCCEEDED(hres)){
+        verify_pidl(pidl, afile2W);
+        ILFree(pidl);
+    }
+
     /* set FIND_DATA struct to NULLs */
     pidl = (ITEMIDLIST*)0xdeadbeef;
     fsbdVtbl.GetFindData = fsbd_GetFindData_nul;
@@ -4145,6 +4160,14 @@ static void test_ParseDisplayNamePBC(void)
         ILFree(pidl);
     }
 
+    hres = IShellFolder_ParseDisplayName(psf, NULL, pbc, afile2W, NULL, &pidl, NULL);
+    ok(hres == S_OK || broken(hres == E_FAIL) /* NT4 */,
+            "ParseDisplayName failed: 0x%08x\n", hres);
+    if(SUCCEEDED(hres)){
+        verify_pidl(pidl, afile2W);
+        ILFree(pidl);
+    }
+
     /* set FIND_DATA struct to junk */
     pidl = (ITEMIDLIST*)0xdeadbeef;
     fsbdVtbl.GetFindData = fsbd_GetFindData_junk;
@@ -4164,6 +4187,14 @@ static void test_ParseDisplayNamePBC(void)
         ILFree(pidl);
     }
 
+    hres = IShellFolder_ParseDisplayName(psf, NULL, pbc, afile2W, NULL, &pidl, NULL);
+    ok(hres == S_OK || broken(hres == E_FAIL) /* NT4 */,
+            "ParseDisplayName failed: 0x%08x\n", hres);
+    if(SUCCEEDED(hres)){
+        verify_pidl(pidl, afile2W);
+        ILFree(pidl);
+    }
+
     /* set FIND_DATA struct to invalid data */
     pidl = (ITEMIDLIST*)0xdeadbeef;
     fsbdVtbl.GetFindData = fsbd_GetFindData_invalid;
@@ -4183,6 +4214,14 @@ static void test_ParseDisplayNamePBC(void)
         ILFree(pidl);
     }
 
+    hres = IShellFolder_ParseDisplayName(psf, NULL, pbc, afile2W, NULL, &pidl, NULL);
+    ok(hres == S_OK || broken(hres == E_FAIL) /* NT4 */,
+            "ParseDisplayName failed: 0x%08x\n", hres);
+    if(SUCCEEDED(hres)){
+        verify_pidl(pidl, afile2W);
+        ILFree(pidl);
+    }
+
     /* set FIND_DATA struct to valid data */
     pidl = (ITEMIDLIST*)0xdeadbeef;
     fsbdVtbl.GetFindData = fsbd_GetFindData_valid;
@@ -4202,6 +4241,14 @@ static void test_ParseDisplayNamePBC(void)
         ILFree(pidl);
     }
 
+    hres = IShellFolder_ParseDisplayName(psf, NULL, pbc, afile2W, NULL, &pidl, NULL);
+    ok(hres == S_OK || broken(hres == E_FAIL) /* NT4 */,
+            "ParseDisplayName failed: 0x%08x\n", hres);
+    if(SUCCEEDED(hres)){
+        verify_pidl(pidl, afile2W);
+        ILFree(pidl);
+    }
+
     IBindCtx_Release(pbc);
     IShellFolder_Release(psf);
 }




More information about the wine-cvs mailing list