Jacek Caban : shlwapi: Fix PathUndecorate[AW] implementation.

Alexandre Julliard julliard at winehq.org
Tue Nov 12 16:56:08 CST 2019


Module: wine
Branch: master
Commit: f3c1d663a4a4a99b5c07000cb0ad9cc55d1e1c88
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=f3c1d663a4a4a99b5c07000cb0ad9cc55d1e1c88

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Tue Nov 12 21:48:23 2019 +0100

shlwapi: Fix PathUndecorate[AW] implementation.

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/shlwapi/path.c       | 76 +++++++++++++++++++----------------------------
 dlls/shlwapi/tests/path.c | 41 +++++++++++++++++++++++++
 2 files changed, 71 insertions(+), 46 deletions(-)

diff --git a/dlls/shlwapi/path.c b/dlls/shlwapi/path.c
index e7b56a7ade..aa43b30b5c 100644
--- a/dlls/shlwapi/path.c
+++ b/dlls/shlwapi/path.c
@@ -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));
 }
 
 /*************************************************************************
diff --git a/dlls/shlwapi/tests/path.c b/dlls/shlwapi/tests/path.c
index 4a6fbd91f6..c5142b992a 100644
--- a/dlls/shlwapi/tests/path.c
+++ b/dlls/shlwapi/tests/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();
 }




More information about the wine-cvs mailing list