From 90ebafd9485a11e60a71672d5893e4d5d691f294 Mon Sep 17 00:00:00 2001 From: Katayama Hirofumi MZ Date: Sun, 17 Mar 2024 08:15:08 +0900 Subject: [PATCH] [RAPPS][SHLWAPI][SDK] Un-escape URL filename (#6626) 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 | 31 ++++++++++++++++++++++++++++- dll/win32/shlwapi/path.c | 2 ++ sdk/include/reactos/shlwapi_undoc.h | 15 ++++++++++++++ 3 files changed, 47 insertions(+), 1 deletion(-) diff --git a/base/applications/rapps/loaddlg.cpp b/base/applications/rapps/loaddlg.cpp index d76e666e042..0433463a8f5 100644 --- a/base/applications/rapps/loaddlg.cpp +++ b/base/applications/rapps/loaddlg.cpp @@ -42,6 +42,7 @@ #include #include +#include #include #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((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] && diff --git a/dll/win32/shlwapi/path.c b/dll/win32/shlwapi/path.c index b1b55b3f244..c26263152df 100644 --- a/dll/win32/shlwapi/path.c +++ b/dll/win32/shlwapi/path.c @@ -4314,6 +4314,7 @@ HRESULT WINAPI SHGetWebFolderFilePathW(LPCWSTR lpszFile, LPWSTR lpszPath, DWORD return E_FAIL; } +#ifndef __REACTOS__ /* Defined in */ #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[] = { diff --git a/sdk/include/reactos/shlwapi_undoc.h b/sdk/include/reactos/shlwapi_undoc.h index 1a46c7b7438..113a232f8d1 100644 --- a/sdk/include/reactos/shlwapi_undoc.h +++ b/sdk/include/reactos/shlwapi_undoc.h @@ -272,9 +272,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);