Module: wine Branch: master Commit: 2f05b5a6d981d54f272d193ea0bcd3a72144c88d URL: http://source.winehq.org/git/wine.git/?a=commit;h=2f05b5a6d981d54f272d193ea0...
Author: Andrew Eikum aeikum@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); }