diff --git a/dll/win32/shlwapi/path.c b/dll/win32/shlwapi/path.c index c26263152df..09acc200e12 100644 --- a/dll/win32/shlwapi/path.c +++ b/dll/win32/shlwapi/path.c @@ -4061,31 +4061,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(LPSTR pszPath) { - 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(pszPath)); + + if (!pszPath) return; + + ext = PathFindExtensionA(pszPath); + if (ext == pszPath || ext[-1] != ']') return; + + skip = ext - 2; + while (skip > pszPath && '0' <= *skip && *skip <= '9') + skip--; + + if (skip > pszPath && *skip == '[' && skip[-1] != '\\') + memmove(skip, ext, strlen(ext) + 1); } /************************************************************************* @@ -4093,31 +4085,23 @@ VOID WINAPI PathUndecorateA(LPSTR lpszPath) * * See PathUndecorateA. */ -VOID WINAPI PathUndecorateW(LPWSTR lpszPath) +void WINAPI PathUndecorateW(LPWSTR pszPath) { - 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 && isdigitW(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(pszPath)); + + if (!pszPath) return; + + ext = PathFindExtensionW(pszPath); + if (ext == pszPath || ext[-1] != ']') return; + + skip = ext - 2; + while (skip > pszPath && '0' <= *skip && *skip <= '9') + skip--; + + if (skip > pszPath && *skip == '[' && skip[-1] != '\\') + memmove(skip, ext, (wcslen(ext) + 1) * sizeof(WCHAR)); } /************************************************************************* diff --git a/modules/rostests/winetests/shlwapi/path.c b/modules/rostests/winetests/shlwapi/path.c index 4a6fbd91f6d..c5142b992aa 100644 --- a/modules/rostests/winetests/shlwapi/path.c +++ b/modules/rostests/winetests/shlwapi/path.c @@ -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(); }