1
0
Fork 0
mirror of synced 2025-03-07 03:53:26 +01:00

shell32: Sanitize Program Manager icon and group names.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52506
This commit is contained in:
Alex Henrie 2022-10-14 09:51:08 -06:00 committed by Alexandre Julliard
parent 6004f5b0da
commit 52ffd611de
2 changed files with 29 additions and 14 deletions

View file

@ -91,16 +91,32 @@ static inline BOOL Dde_OnWildConnect(HSZ hszTopic, HSZ hszService)
return FALSE; return FALSE;
} }
static WCHAR *combine_path(const WCHAR *directory, const WCHAR *name, const WCHAR *extension) static WCHAR *combine_path(const WCHAR *directory, const WCHAR *name, const WCHAR *extension, BOOL sanitize)
{ {
WCHAR *path; WCHAR *path;
int len; int len, i;
len = wcslen(directory) + 1 + wcslen(name); len = wcslen(directory) + 1 + wcslen(name);
if (extension) len += wcslen(extension); if (extension) len += wcslen(extension);
path = malloc((len + 1) * sizeof(WCHAR)); path = malloc((len + 1) * sizeof(WCHAR));
PathCombineW(path, directory, name); if (sanitize)
{
WCHAR *sanitized_name = wcsdup(name);
for (i = 0; i < wcslen(name); i++)
{
if (name[i] < ' ' || wcschr(L"*/:<>?\\|", name[i]))
sanitized_name[i] = '_';
}
PathCombineW(path, directory, sanitized_name);
free(sanitized_name);
}
else
{
PathCombineW(path, directory, name);
}
if (extension) if (extension)
wcscat(path, extension); wcscat(path, extension);
@ -109,12 +125,12 @@ static WCHAR *combine_path(const WCHAR *directory, const WCHAR *name, const WCHA
} }
/* Returned string must be freed by caller */ /* Returned string must be freed by caller */
static WCHAR *get_programs_path(const WCHAR *name) static WCHAR *get_programs_path(const WCHAR *name, BOOL sanitize)
{ {
WCHAR *programs, *path; WCHAR *programs, *path;
SHGetKnownFolderPath(&FOLDERID_Programs, 0, NULL, &programs); SHGetKnownFolderPath(&FOLDERID_Programs, 0, NULL, &programs);
path = combine_path(programs, name, NULL); path = combine_path(programs, name, NULL, sanitize);
CoTaskMemFree(programs); CoTaskMemFree(programs);
return path; return path;
@ -134,7 +150,7 @@ static inline HDDEDATA Dde_OnRequest(UINT uFmt, HCONV hconv, HSZ hszTopic,
HDDEDATA ret; HDDEDATA ret;
groups_data[0] = 0; groups_data[0] = 0;
programs = get_programs_path(L"*"); programs = get_programs_path(L"*", FALSE);
hfind = FindFirstFileW(programs, &finddata); hfind = FindFirstFileW(programs, &finddata);
if (hfind) if (hfind)
{ {
@ -185,7 +201,7 @@ static DWORD PROGMAN_OnExecute(WCHAR *command, int argc, WCHAR **argv)
if (argc < 1) return DDE_FNOTPROCESSED; if (argc < 1) return DDE_FNOTPROCESSED;
path = get_programs_path(argv[0]); path = get_programs_path(argv[0], TRUE);
CreateDirectoryW(path, NULL); CreateDirectoryW(path, NULL);
ShellExecuteW(NULL, NULL, path, NULL, NULL, SW_SHOWNORMAL); ShellExecuteW(NULL, NULL, path, NULL, NULL, SW_SHOWNORMAL);
@ -201,7 +217,7 @@ static DWORD PROGMAN_OnExecute(WCHAR *command, int argc, WCHAR **argv)
if (argc < 1) return DDE_FNOTPROCESSED; if (argc < 1) return DDE_FNOTPROCESSED;
path = get_programs_path(argv[0]); path = get_programs_path(argv[0], TRUE);
path2 = malloc((lstrlenW(path) + 2) * sizeof(*path)); path2 = malloc((lstrlenW(path) + 2) * sizeof(*path));
lstrcpyW(path2, path); lstrcpyW(path2, path);
@ -226,7 +242,7 @@ static DWORD PROGMAN_OnExecute(WCHAR *command, int argc, WCHAR **argv)
* ignore its actual value. */ * ignore its actual value. */
if (argc < 2) return DDE_FNOTPROCESSED; if (argc < 2) return DDE_FNOTPROCESSED;
path = get_programs_path(argv[0]); path = get_programs_path(argv[0], TRUE);
ShellExecuteW(NULL, NULL, path, NULL, NULL, SW_SHOWNORMAL); ShellExecuteW(NULL, NULL, path, NULL, NULL, SW_SHOWNORMAL);
@ -275,14 +291,14 @@ static DWORD PROGMAN_OnExecute(WCHAR *command, int argc, WCHAR **argv)
} }
if (argc >= 2) if (argc >= 2)
{ {
name = combine_path(last_group, argv[1], L".lnk"); name = combine_path(last_group, argv[1], L".lnk", TRUE);
} }
else else
{ {
WCHAR *filename = wcsdup(PathFindFileNameW(argv[0])); WCHAR *filename = wcsdup(PathFindFileNameW(argv[0]));
WCHAR *ext = PathFindExtensionW(filename); WCHAR *ext = PathFindExtensionW(filename);
*ext = '\0'; *ext = '\0';
name = combine_path(last_group, filename, L".lnk"); name = combine_path(last_group, filename, L".lnk", TRUE);
free(filename); free(filename);
} }
hres = IPersistFile_Save(file, name, TRUE); hres = IPersistFile_Save(file, name, TRUE);
@ -300,7 +316,7 @@ static DWORD PROGMAN_OnExecute(WCHAR *command, int argc, WCHAR **argv)
if (argc < 1) return DDE_FNOTPROCESSED; if (argc < 1) return DDE_FNOTPROCESSED;
name = combine_path(last_group, argv[0], L".lnk"); name = combine_path(last_group, argv[0], L".lnk", FALSE);
ret = DeleteFileW(name); ret = DeleteFileW(name);
free(name); free(name);

View file

@ -459,8 +459,7 @@ static void test_name_sanitization(DWORD instance, HCONV hConv)
error = dde_execute(instance, hConv, buf); error = dde_execute(instance, hConv, buf);
ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %#x\n", error); ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %#x\n", error);
sprintf(buf, "Group%s", sanitized_name); sprintf(buf, "Group%s", sanitized_name);
todo_wine ok(check_exists(buf), "directory not created\n"); ok(check_exists(buf), "directory not created\n");
if (!check_exists(buf)) return;
ok(check_window_exists(buf), "window not created\n"); ok(check_window_exists(buf), "window not created\n");
sprintf(buf, "[ShowGroup(\"Group%s\", 0)]", original_name); sprintf(buf, "[ShowGroup(\"Group%s\", 0)]", original_name);