https://git.reactos.org/?p=reactos.git;a=commitdiff;h=99b52df014e004531ab638...
commit 99b52df014e004531ab6389284e087b9bb8837cf Author: Katayama Hirofumi MZ katayama.hirofumi.mz@gmail.com AuthorDate: Thu May 28 10:58:26 2020 +0900 Commit: GitHub noreply@github.com CommitDate: Thu May 28 10:58:26 2020 +0900
[SHELL32][INCLUDE] Improve CheckEscapesA/W (#2795)
Fix and improve shell32!CheckEscapesA/W functions. Add a testcase for shell32!CheckEscapesA/W to shell32_apitest. --- dll/win32/shell32/wine/shellstring.c | 38 ++--- modules/rostests/apitests/shell32/CMakeLists.txt | 1 + modules/rostests/apitests/shell32/CheckEscapes.cpp | 177 +++++++++++++++++++++ modules/rostests/apitests/shell32/testlist.c | 2 + sdk/include/reactos/undocshell.h | 4 +- 5 files changed, 198 insertions(+), 24 deletions(-)
diff --git a/dll/win32/shell32/wine/shellstring.c b/dll/win32/shell32/wine/shellstring.c index 8bccd1c1563..8796f3813c3 100644 --- a/dll/win32/shell32/wine/shellstring.c +++ b/dll/win32/shell32/wine/shellstring.c @@ -30,6 +30,7 @@
#include "shell32_main.h" #include "undocshell.h" +#include "shlwapi_undoc.h"
WINE_DEFAULT_DEBUG_CHANNEL(shell);
@@ -222,30 +223,25 @@ BOOL WINAPI OleStrToStrNAW (LPVOID lpOut, INT nOut, LPCVOID lpIn, INT nIn) * PARAMS * string [I/O] string to check and on return eventually quoted * len [I] length of string - * - * RETURNS - * length of actual string - * - * NOTES - * Not really sure if this function returns actually a value at all. */ -DWORD WINAPI CheckEscapesA( +VOID WINAPI CheckEscapesA( LPSTR string, /* [I/O] string to check ??*/ DWORD len) /* [I] is 0 */ { - LPWSTR wString; - DWORD ret = 0; + LPWSTR wString; + TRACE("(%s %d)\n", debugstr_a(string), len);
- TRACE("(%s %d)\n", debugstr_a(string), len); - wString = LocalAlloc(LPTR, len * sizeof(WCHAR)); - if (wString) - { - MultiByteToWideChar(CP_ACP, 0, string, len, wString, len); - ret = CheckEscapesW(wString, len); - WideCharToMultiByte(CP_ACP, 0, wString, len, string, len, NULL, NULL); - LocalFree(wString); - } - return ret; + if (!string || !string[0]) + return; + + wString = LocalAlloc(LPTR, len * sizeof(WCHAR)); + if (!wString) + return; + + SHAnsiToUnicode(string, wString, len); + CheckEscapesW(wString, len); + SHUnicodeToAnsi(wString, string, len); + LocalFree(wString); }
static const WCHAR strEscapedChars[] = {' ','"',',',';','^',0}; @@ -255,7 +251,7 @@ static const WCHAR strEscapedChars[] = {' ','"',',',';','^',0}; * * See CheckEscapesA. */ -DWORD WINAPI CheckEscapesW( +VOID WINAPI CheckEscapesW( LPWSTR string, DWORD len) { @@ -273,7 +269,5 @@ DWORD WINAPI CheckEscapesW( for (;d > string;) *d-- = *s--; *d = '"'; - return size + 2; } - return size; } diff --git a/modules/rostests/apitests/shell32/CMakeLists.txt b/modules/rostests/apitests/shell32/CMakeLists.txt index 3425c187d73..9bff4a9c09a 100644 --- a/modules/rostests/apitests/shell32/CMakeLists.txt +++ b/modules/rostests/apitests/shell32/CMakeLists.txt @@ -11,6 +11,7 @@ include_directories(${REACTOS_SOURCE_DIR}/sdk/lib/atl) list(APPEND SOURCE AddCommas.cpp CFSFolder.cpp + CheckEscapes.cpp CIDLData.cpp CMyComputer.cpp CShellDesktop.cpp diff --git a/modules/rostests/apitests/shell32/CheckEscapes.cpp b/modules/rostests/apitests/shell32/CheckEscapes.cpp new file mode 100644 index 00000000000..095dbaf766d --- /dev/null +++ b/modules/rostests/apitests/shell32/CheckEscapes.cpp @@ -0,0 +1,177 @@ +/* + * PROJECT: ReactOS API tests + * LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory + * PURPOSE: Test for CheckEscapesA/W + * PROGRAMMER: Katayama Hirofumi MZ katayama.hirofumi.mz@gmail.com + */ +#include "shelltest.h" + +typedef void (WINAPI *FN_CheckEscapesA)(LPSTR string, DWORD len); +typedef void (WINAPI *FN_CheckEscapesW)(LPWSTR string, DWORD len); + +static FN_CheckEscapesA s_pCheckEscapesA; +static FN_CheckEscapesW s_pCheckEscapesW; + +typedef struct TESTENTRYA +{ + INT lineno; + LPCSTR input; + DWORD len; + LPCSTR output; +} TESTENTRYA; + +typedef struct TESTENTRYW +{ + INT lineno; + LPCWSTR input; + DWORD len; + LPCWSTR output; +} TESTENTRYW; + +static const TESTENTRYA s_entriesA[] = +{ + { __LINE__, "", 0, "" }, + { __LINE__, "", 1, "" }, + { __LINE__, "", 2, "" }, + { __LINE__, "", 3, "" }, + { __LINE__, "", 4, "" }, + { __LINE__, "", 5, "" }, + { __LINE__, "", 6, "" }, + { __LINE__, "ABC", 1, "" }, + { __LINE__, "ABC", 2, "A" }, + { __LINE__, "ABC", 3, "AB" }, + { __LINE__, "ABC", 4, "ABC" }, + { __LINE__, "ABC", 5, "ABC" }, + { __LINE__, "ABC", 6, "ABC" }, + { __LINE__, "AB C", 1, "" }, + { __LINE__, "AB C", 2, "A" }, + { __LINE__, "AB C", 3, "AB" }, + { __LINE__, "AB C", 4, "AB " }, + { __LINE__, "AB C", 5, "AB C" }, + { __LINE__, "AB C", 6, ""AB C" }, + { __LINE__, "AB C ", 1, "" }, + { __LINE__, "AB C ", 2, "A" }, + { __LINE__, "AB C ", 3, "AB" }, + { __LINE__, "AB C ", 4, "AB " }, + { __LINE__, "AB C ", 5, "AB C" }, + { __LINE__, "AB C ", 6, "AB C " }, + { __LINE__, "AB,", 1, "" }, + { __LINE__, "AB,", 2, "A" }, + { __LINE__, "AB,", 3, "AB" }, + { __LINE__, "AB,", 4, "AB," }, + { __LINE__, "AB,", 5, ""AB," }, + { __LINE__, "AB,", 6, ""AB,"" }, + { __LINE__, "AB"", 1, "" }, + { __LINE__, "AB"", 2, "A" }, + { __LINE__, "AB"", 3, "AB" }, + { __LINE__, "AB"", 4, "AB"" }, + { __LINE__, "AB"", 5, ""AB"" }, + { __LINE__, "AB"", 6, ""AB""" }, + { __LINE__, "AB;", 1, "" }, + { __LINE__, "AB;", 2, "A" }, + { __LINE__, "AB;", 3, "AB" }, + { __LINE__, "AB;", 4, "AB;" }, + { __LINE__, "AB;", 5, ""AB;" }, + { __LINE__, "AB;", 6, ""AB;"" }, + { __LINE__, "AB^", 1, "" }, + { __LINE__, "AB^", 2, "A" }, + { __LINE__, "AB^", 3, "AB" }, + { __LINE__, "AB^", 4, "AB^" }, + { __LINE__, "AB^", 5, ""AB^" }, + { __LINE__, "AB^", 6, ""AB^"" }, +}; + +static const TESTENTRYW s_entriesW[] = +{ + { __LINE__, L"", 0, L"" }, + { __LINE__, L"", 1, L"" }, + { __LINE__, L"", 2, L"" }, + { __LINE__, L"", 3, L"" }, + { __LINE__, L"", 4, L"" }, + { __LINE__, L"", 5, L"" }, + { __LINE__, L"", 6, L"" }, + { __LINE__, L"ABC", 1, L"ABC" }, + { __LINE__, L"ABC", 2, L"ABC" }, + { __LINE__, L"ABC", 3, L"ABC" }, + { __LINE__, L"ABC", 4, L"ABC" }, + { __LINE__, L"ABC", 5, L"ABC" }, + { __LINE__, L"ABC", 6, L"ABC" }, + { __LINE__, L"AB C", 1, L"AB C" }, + { __LINE__, L"AB C", 2, L"AB C" }, + { __LINE__, L"AB C", 3, L"AB C" }, + { __LINE__, L"AB C", 4, L"AB C" }, + { __LINE__, L"AB C", 5, L"AB C" }, + { __LINE__, L"AB C", 6, L""AB C"" }, + { __LINE__, L"AB C ", 1, L"AB C " }, + { __LINE__, L"AB C ", 2, L"AB C " }, + { __LINE__, L"AB C ", 3, L"AB C " }, + { __LINE__, L"AB C ", 4, L"AB C " }, + { __LINE__, L"AB C ", 5, L"AB C " }, + { __LINE__, L"AB C ", 6, L"AB C " }, + { __LINE__, L"AB,", 1, L"AB," }, + { __LINE__, L"AB,", 2, L"AB," }, + { __LINE__, L"AB,", 3, L"AB," }, + { __LINE__, L"AB,", 4, L"AB," }, + { __LINE__, L"AB,", 5, L""AB,"" }, + { __LINE__, L"AB,", 6, L""AB,"" }, + { __LINE__, L"AB"", 1, L"AB"" }, + { __LINE__, L"AB"", 2, L"AB"" }, + { __LINE__, L"AB"", 3, L"AB"" }, + { __LINE__, L"AB"", 4, L"AB"" }, + { __LINE__, L"AB"", 5, L""AB""" }, + { __LINE__, L"AB"", 6, L""AB""" }, + { __LINE__, L"AB;", 1, L"AB;" }, + { __LINE__, L"AB;", 2, L"AB;" }, + { __LINE__, L"AB;", 3, L"AB;" }, + { __LINE__, L"AB;", 4, L"AB;" }, + { __LINE__, L"AB;", 5, L""AB;"" }, + { __LINE__, L"AB;", 6, L""AB;"" }, + { __LINE__, L"AB^", 1, L"AB^" }, + { __LINE__, L"AB^", 2, L"AB^" }, + { __LINE__, L"AB^", 3, L"AB^" }, + { __LINE__, L"AB^", 4, L"AB^" }, + { __LINE__, L"AB^", 5, L""AB^"" }, + { __LINE__, L"AB^", 6, L""AB^"" }, +}; + +static void JustDoIt(void) +{ + SIZE_T i, count; + CHAR bufA[MAX_PATH]; + WCHAR bufW[MAX_PATH]; + + count = _countof(s_entriesA); + for (i = 0; i < count; ++i) + { + lstrcpynA(bufA, s_entriesA[i].input, _countof(bufA)); + s_pCheckEscapesA(bufA, s_entriesA[i].len); + ok(lstrcmpA(bufA, s_entriesA[i].output) == 0, + "Line %d: output expected '%s' vs got '%s'\n", + s_entriesA[i].lineno, s_entriesA[i].output, bufA); + } + + count = _countof(s_entriesW); + for (i = 0; i < count; ++i) + { + lstrcpynW(bufW, s_entriesW[i].input, _countof(bufW)); + s_pCheckEscapesW(bufW, s_entriesW[i].len); + ok(lstrcmpW(bufW, s_entriesW[i].output) == 0, + "Line %d: output expected '%ls' vs got '%ls'\n", + s_entriesW[i].lineno, s_entriesW[i].output, bufW); + } +} + +START_TEST(CheckEscapes) +{ + HINSTANCE hShell32 = GetModuleHandleA("shell32"); + s_pCheckEscapesA = (FN_CheckEscapesA)GetProcAddress(hShell32, "CheckEscapesA"); + s_pCheckEscapesW = (FN_CheckEscapesW)GetProcAddress(hShell32, "CheckEscapesW"); + if (s_pCheckEscapesA && s_pCheckEscapesW) + { + JustDoIt(); + } + else + { + skip("There is no CheckEscapesA/W\n"); + } +} diff --git a/modules/rostests/apitests/shell32/testlist.c b/modules/rostests/apitests/shell32/testlist.c index ba56769a97a..74c90e013c6 100644 --- a/modules/rostests/apitests/shell32/testlist.c +++ b/modules/rostests/apitests/shell32/testlist.c @@ -6,6 +6,7 @@ extern void func_AddCommas(void); extern void func_Control_RunDLLW(void); extern void func_CFSFolder(void); +extern void func_CheckEscapes(void); extern void func_CIDLData(void); extern void func_CMyComputer(void); extern void func_CShellDesktop(void); @@ -33,6 +34,7 @@ const struct test winetest_testlist[] = { "AddCommas", func_AddCommas }, { "Control_RunDLLW", func_Control_RunDLLW }, { "CFSFolder", func_CFSFolder }, + { "CheckEscapes", func_CheckEscapes }, { "CIDLData", func_CIDLData }, { "CMyComputer", func_CMyComputer }, { "CShellDesktop", func_CShellDesktop }, diff --git a/sdk/include/reactos/undocshell.h b/sdk/include/reactos/undocshell.h index 3b7c5d6463c..4e55a38e274 100644 --- a/sdk/include/reactos/undocshell.h +++ b/sdk/include/reactos/undocshell.h @@ -611,8 +611,8 @@ HRESULT WINAPI SHCreateLinks( UINT uFlags, LPITEMIDLIST *lppidlLinks);
-DWORD WINAPI CheckEscapesA(LPSTR string, DWORD len); -DWORD WINAPI CheckEscapesW(LPWSTR string, DWORD len); +VOID WINAPI CheckEscapesA(LPSTR string, DWORD len); +VOID WINAPI CheckEscapesW(LPWSTR string, DWORD len);
/* policy functions */ BOOL WINAPI SHInitRestricted(LPCVOID unused, LPCVOID inpRegKey);