[RAPPS][SHLWAPI][SDK] Un-escape URL filename (#6626)
authorKatayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
Sat, 16 Mar 2024 23:15:08 +0000 (08:15 +0900)
committerGitHub <noreply@github.com>
Sat, 16 Mar 2024 23:15:08 +0000 (08:15 +0900)
Choosing the better filename.
JIRA issue: CORE-19490
- Add UrlUnescapeAndMakeFileNameValid helper function.
- Use UrlUnescapeW and PathIsValidCharW.
- Add PATH_CHAR_CLASS_... flags for PathIsValidCharA/W.

base/applications/rapps/loaddlg.cpp
dll/win32/shlwapi/path.c
sdk/include/reactos/shlwapi_undoc.h

index d76e666..0433463 100644 (file)
@@ -42,6 +42,7 @@
 
 #include <ui/rosctrls.h>
 #include <windowsx.h>
+#include <shlwapi_undoc.h>
 #include <process.h>
 #undef SubclassWindow
 
@@ -80,6 +81,30 @@ LoadStatusString(DownloadStatus StatusParam)
     return szString;
 }
 
+#define FILENAME_VALID_CHAR ( \
+    PATH_CHAR_CLASS_LETTER      | \
+    PATH_CHAR_CLASS_DOT         | \
+    PATH_CHAR_CLASS_SEMICOLON   | \
+    PATH_CHAR_CLASS_COMMA       | \
+    PATH_CHAR_CLASS_SPACE       | \
+    PATH_CHAR_CLASS_OTHER_VALID)
+
+VOID
+UrlUnescapeAndMakeFileNameValid(CStringW& str)
+{
+    WCHAR szPath[MAX_PATH];
+    DWORD cchPath = _countof(szPath);
+    UrlUnescapeW(const_cast<LPWSTR>((LPCWSTR)str), szPath, &cchPath, 0);
+
+    for (PWCHAR pch = szPath; *pch; ++pch)
+    {
+        if (!PathIsValidCharW(*pch, FILENAME_VALID_CHAR))
+            *pch = L'_';
+    }
+
+    str = szPath;
+}
+
 struct DownloadInfo
 {
     DownloadInfo()
@@ -710,8 +735,12 @@ CDownloadManager::ThreadFunc(LPVOID param)
                 Path += APPLICATION_DATABASE_NAME;
                 break;
             case DLTYPE_APPLICATION:
-                Path += (LPWSTR)(p + 1); // use the filename retrieved from URL
+            {
+                CStringW str = p + 1; // use the filename retrieved from URL
+                UrlUnescapeAndMakeFileNameValid(str);
+                Path += str;
                 break;
+            }
         }
 
         if ((InfoArray[iAppId].DLType == DLTYPE_APPLICATION) && InfoArray[iAppId].szSHA1[0] &&
index b1b55b3..c262631 100644 (file)
@@ -4314,6 +4314,7 @@ HRESULT WINAPI SHGetWebFolderFilePathW(LPCWSTR lpszFile, LPWSTR lpszPath, DWORD
   return E_FAIL;
 }
 
+#ifndef __REACTOS__ /* Defined in <shlwapi_undoc.h> */
 #define PATH_CHAR_CLASS_LETTER      0x00000001
 #define PATH_CHAR_CLASS_ASTERIX     0x00000002
 #define PATH_CHAR_CLASS_DOT         0x00000004
@@ -4327,6 +4328,7 @@ HRESULT WINAPI SHGetWebFolderFilePathW(LPCWSTR lpszFile, LPWSTR lpszPath, DWORD
 
 #define PATH_CHAR_CLASS_INVALID     0x00000000
 #define PATH_CHAR_CLASS_ANY         0xffffffff
+#endif
 
 static const DWORD SHELL_charclass[] =
 {
index 1f37c8a..ff2f81f 100644 (file)
@@ -294,9 +294,24 @@ ShellMessageBoxWrapW(
 
 #define WHICH_DEFAULT   (WHICH_PIF | WHICH_COM | WHICH_EXE | WHICH_BAT | WHICH_LNK | WHICH_CMD)
 
+/* dwClass flags for PathIsValidCharA and PathIsValidCharW */
+#define PATH_CHAR_CLASS_LETTER      0x00000001
+#define PATH_CHAR_CLASS_ASTERIX     0x00000002
+#define PATH_CHAR_CLASS_DOT         0x00000004
+#define PATH_CHAR_CLASS_BACKSLASH   0x00000008
+#define PATH_CHAR_CLASS_COLON       0x00000010
+#define PATH_CHAR_CLASS_SEMICOLON   0x00000020
+#define PATH_CHAR_CLASS_COMMA       0x00000040
+#define PATH_CHAR_CLASS_SPACE       0x00000080
+#define PATH_CHAR_CLASS_OTHER_VALID 0x00000100
+#define PATH_CHAR_CLASS_DOUBLEQUOTE 0x00000200
+#define PATH_CHAR_CLASS_INVALID     0x00000000
+#define PATH_CHAR_CLASS_ANY         0xffffffff
+
 BOOL WINAPI PathFileExistsDefExtW(LPWSTR lpszPath, DWORD dwWhich);
 BOOL WINAPI PathFindOnPathExW(LPWSTR lpszFile, LPCWSTR *lppszOtherDirs, DWORD dwWhich);
 VOID WINAPI FixSlashesAndColonW(LPWSTR);
+BOOL WINAPI PathIsValidCharA(char c, DWORD dwClass);
 BOOL WINAPI PathIsValidCharW(WCHAR c, DWORD dwClass);
 BOOL WINAPI SHGetPathFromIDListWrapW(LPCITEMIDLIST pidl, LPWSTR pszPath);