https://git.reactos.org/?p=reactos.git;a=commitdiff;h=f189d8c45461cdfe03801fdbb8647c3efe1ff3c3
commit f189d8c45461cdfe03801fdbb8647c3efe1ff3c3 Author: Jacek Caban <ja...@codeweavers.com> AuthorDate: Tue Nov 12 21:48:23 2019 +0100 Commit: Hermès Bélusca-Maïto <hermes.belusca-ma...@reactos.org> CommitDate: Sat Jan 18 16:39:36 2025 +0100 [SHLWAPI][WINESYNC] Import PathUndecorate wine fix + adaptation for ReactOS (#7636) shlwapi: Fix PathUndecorate[AW] implementation. Signed-off-by: Jacek Caban <ja...@codeweavers.com> Signed-off-by: Alexandre Julliard <julli...@winehq.org> wine commit id f3c1d663a4a4a99b5c07000cb0ad9cc55d1e1c88 by Jacek Caban <ja...@codeweavers.com> Co-authored-by: Hermès Bélusca-Maïto <hermes.belusca-ma...@reactos.org> --- dll/win32/shlwapi/path.c | 76 ++++++++++++------------------- modules/rostests/winetests/shlwapi/path.c | 41 +++++++++++++++++ 2 files changed, 71 insertions(+), 46 deletions(-) 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(); }