shlwapi: Fix PathUndecorate[AW] implementation.

Signed-off-by: Jacek Caban <jacek@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Jacek Caban 2019-11-12 21:48:23 +01:00 committed by Alexandre Julliard
parent db77f53507
commit f3c1d663a4
2 changed files with 71 additions and 46 deletions

View file

@ -1440,31 +1440,23 @@ LPCWSTR WINAPI PathFindSuffixArrayW(LPCWSTR lpszSuffix, LPCWSTR *lppszArray, int
* NOTES
* A decorations form is "path[n].ext" where "n" is an optional decimal number.
*/
VOID WINAPI PathUndecorateA(LPSTR lpszPath)
void WINAPI PathUndecorateA(char *path)
{
TRACE("(%s)\n",debugstr_a(lpszPath));
char *ext, *skip;
if (lpszPath)
{
LPSTR lpszExt = PathFindExtensionA(lpszPath);
if (lpszExt > lpszPath && lpszExt[-1] == ']')
{
LPSTR lpszSkip = lpszExt - 2;
if (*lpszSkip == '[')
lpszSkip++; /* [] (no number) */
else
while (lpszSkip > lpszPath && isdigit(lpszSkip[-1]))
lpszSkip--;
if (lpszSkip > lpszPath && lpszSkip[-1] == '[' && lpszSkip[-2] != '\\')
{
/* remove the [n] */
lpszSkip--;
while (*lpszExt)
*lpszSkip++ = *lpszExt++;
*lpszSkip = '\0';
}
}
}
TRACE("(%s)\n", debugstr_a(path));
if (!path) return;
ext = PathFindExtensionA(path);
if (ext == path || ext[-1] != ']') return;
skip = ext - 2;
while (skip > path && '0' <= *skip && *skip <= '9')
skip--;
if (skip > path && *skip == '[' && skip[-1] != '\\')
memmove(skip, ext, strlen(ext) + 1);
}
/*************************************************************************
@ -1472,31 +1464,23 @@ VOID WINAPI PathUndecorateA(LPSTR lpszPath)
*
* See PathUndecorateA.
*/
VOID WINAPI PathUndecorateW(LPWSTR lpszPath)
void WINAPI PathUndecorateW(WCHAR *path)
{
TRACE("(%s)\n",debugstr_w(lpszPath));
WCHAR *ext, *skip;
if (lpszPath)
{
LPWSTR lpszExt = PathFindExtensionW(lpszPath);
if (lpszExt > lpszPath && lpszExt[-1] == ']')
{
LPWSTR lpszSkip = lpszExt - 2;
if (*lpszSkip == '[')
lpszSkip++; /* [] (no number) */
else
while (lpszSkip > lpszPath && iswdigit(lpszSkip[-1]))
lpszSkip--;
if (lpszSkip > lpszPath && lpszSkip[-1] == '[' && lpszSkip[-2] != '\\')
{
/* remove the [n] */
lpszSkip--;
while (*lpszExt)
*lpszSkip++ = *lpszExt++;
*lpszSkip = '\0';
}
}
}
TRACE("(%s)\n", debugstr_w(path));
if (!path) return;
ext = PathFindExtensionW(path);
if (ext == path || ext[-1] != ']') return;
skip = ext - 2;
while (skip > path && '0' <= *skip && *skip <= '9')
skip--;
if (skip > path && *skip == '[' && skip[-1] != '\\')
memmove(skip, ext, (wcslen(ext) + 1) * sizeof(WCHAR));
}
/*************************************************************************

View file

@ -1672,6 +1672,46 @@ static void test_PathStripPathA(void)
PathStripPathA((char*)const_path);
}
static void test_PathUndecorate(void)
{
static const struct {
const WCHAR *path;
const WCHAR *expect;
} tests[] = {
{ L"c:\\test\\a[123]", L"c:\\test\\a" },
{ L"c:\\test\\a[123].txt", L"c:\\test\\a.txt" },
{ L"c:\\test\\a.txt[123]", L"c:\\test\\a.txt[123]" },
{ L"c:\\test\\a[123a].txt", L"c:\\test\\a[123a].txt" },
{ L"c:\\test\\a[a123].txt", L"c:\\test\\a[a123].txt" },
{ L"c:\\test\\a[12\x0660].txt", L"c:\\test\\a[12\x0660].txt" },
{ L"c:\\test\\a[12]file", L"c:\\test\\a[12]file" },
{ L"c:\\test[123]\\a", L"c:\\test[123]\\a" },
{ L"c:\\test\\[123]", L"c:\\test\\[123]" },
{ L"a[123]", L"a" },
{ L"a[]", L"a" },
{ L"[123]", L"[123]" }
};
char bufa[MAX_PATH], expect[MAX_PATH];
WCHAR buf[MAX_PATH];
unsigned i;
for (i = 0; i < ARRAY_SIZE(tests); i++)
{
wcscpy(buf, tests[i].path);
PathUndecorateW(buf);
ok(!wcscmp(buf, tests[i].expect), "PathUndecorateW returned %s, expected %s\n",
wine_dbgstr_w(buf), wine_dbgstr_w(tests[i].expect));
WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, tests[i].path, -1, bufa, ARRAY_SIZE(bufa), "?", NULL);
WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, tests[i].expect, -1, expect, ARRAY_SIZE(expect), "?", NULL);
PathUndecorateA(bufa);
ok(!strcmp(bufa, expect), "PathUndecorateA returned %s, expected %s\n", bufa, expect);
}
PathUndecorateA(NULL);
PathUndecorateW(NULL);
}
START_TEST(path)
{
HMODULE hShlwapi = GetModuleHandleA("shlwapi.dll");
@ -1718,4 +1758,5 @@ START_TEST(path)
test_PathIsRelativeA();
test_PathIsRelativeW();
test_PathStripPathA();
test_PathUndecorate();
}