[PATCH v4 1/1] shell32: Sanitize Program Manager icon and group names.
Alex Henrie
wine at gitlab.winehq.org
Mon Jun 20 22:42:25 CDT 2022
From: Alex Henrie <alexhenrie24 at gmail.com>
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52506
Signed-off-by: Alex Henrie <alexhenrie24 at gmail.com>
---
dlls/shell32/dde.c | 69 ++++++++++++++++++++------------
dlls/shell32/tests/progman_dde.c | 3 +-
2 files changed, 45 insertions(+), 27 deletions(-)
diff --git a/dlls/shell32/dde.c b/dlls/shell32/dde.c
index 5ab63136092..d4a9893b65d 100644
--- a/dlls/shell32/dde.c
+++ b/dlls/shell32/dde.c
@@ -78,20 +78,46 @@ static inline BOOL Dde_OnWildConnect(HSZ hszTopic, HSZ hszService)
return FALSE;
}
+static WCHAR *combine_path(const WCHAR *directory, const WCHAR *name, const WCHAR *extension, BOOL sanitize)
+{
+ WCHAR *path;
+ int len, i;
+
+ len = wcslen(directory) + 1 + wcslen(name);
+ if (extension) len += wcslen(extension);
+ path = heap_alloc((len + 1) * sizeof(WCHAR));
+
+ 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);
+ heap_free(sanitized_name);
+ }
+ else
+ {
+ PathCombineW(path, directory, name);
+ }
+
+ if (extension)
+ wcscat(path, extension);
+
+ return path;
+}
+
/* 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;
- int len;
SHGetKnownFolderPath(&FOLDERID_Programs, 0, NULL, &programs);
-
- len = lstrlenW(programs) + 1 + lstrlenW(name);
- path = heap_alloc((len + 1) * sizeof(*path));
- lstrcpyW(path, programs);
- lstrcatW(path, L"/");
- lstrcatW(path, name);
-
+ path = combine_path(programs, name, NULL, sanitize);
CoTaskMemFree(programs);
return path;
@@ -111,7 +137,7 @@ static inline HDDEDATA Dde_OnRequest(UINT uFmt, HCONV hconv, HSZ hszTopic,
HDDEDATA ret;
groups_data[0] = 0;
- programs = get_programs_path(L"*");
+ programs = get_programs_path(L"*", FALSE);
hfind = FindFirstFileW(programs, &finddata);
if (hfind)
{
@@ -162,7 +188,7 @@ static DWORD PROGMAN_OnExecute(WCHAR *command, int argc, WCHAR **argv)
if (argc < 1) return DDE_FNOTPROCESSED;
- path = get_programs_path(argv[0]);
+ path = get_programs_path(argv[0], TRUE);
CreateDirectoryW(path, NULL);
ShellExecuteW(NULL, NULL, path, NULL, NULL, SW_SHOWNORMAL);
@@ -178,7 +204,7 @@ static DWORD PROGMAN_OnExecute(WCHAR *command, int argc, WCHAR **argv)
if (argc < 1) return DDE_FNOTPROCESSED;
- path = get_programs_path(argv[0]);
+ path = get_programs_path(argv[0], TRUE);
path2 = heap_alloc((lstrlenW(path) + 2) * sizeof(*path));
lstrcpyW(path2, path);
@@ -203,7 +229,7 @@ static DWORD PROGMAN_OnExecute(WCHAR *command, int argc, WCHAR **argv)
* ignore its actual value. */
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);
@@ -252,16 +278,13 @@ static DWORD PROGMAN_OnExecute(WCHAR *command, int argc, WCHAR **argv)
}
if (argc >= 2)
{
- len = lstrlenW(last_group) + 1 + lstrlenW(argv[1]) + 5;
- name = heap_alloc(len * sizeof(*name));
- swprintf( name, len, L"%s/%s.lnk", last_group, argv[1] );
+ name = combine_path(last_group, argv[1], L".lnk", TRUE);
}
else
{
- const WCHAR *filename = PathFindFileNameW(argv[0]);
- len = PathFindExtensionW(filename) - filename;
- name = heap_alloc((lstrlenW(last_group) + 1 + len + 5) * sizeof(*name));
- swprintf( name, lstrlenW(last_group) + 1 + len + 5, L"%s/%.*s.lnk", last_group, len, filename );
+ WCHAR *filename = PathFindFileNameW(argv[0]);
+ *PathFindExtensionW(filename) = '\0';
+ name = combine_path(last_group, filename, L".lnk", TRUE);
}
hres = IPersistFile_Save(file, name, TRUE);
@@ -278,12 +301,8 @@ static DWORD PROGMAN_OnExecute(WCHAR *command, int argc, WCHAR **argv)
if (argc < 1) return DDE_FNOTPROCESSED;
- len = lstrlenW(last_group) + 1 + lstrlenW(argv[0]) + 5;
- name = heap_alloc(len * sizeof(*name));
- swprintf( name, len, L"%s/%s.lnk", last_group, argv[0]);
-
+ name = combine_path(last_group, argv[0], L".lnk", FALSE);
ret = DeleteFileW(name);
-
heap_free(name);
if (!ret) return DDE_FNOTPROCESSED;
diff --git a/dlls/shell32/tests/progman_dde.c b/dlls/shell32/tests/progman_dde.c
index cb1ff8ddb9f..5a7e8c912e5 100644
--- a/dlls/shell32/tests/progman_dde.c
+++ b/dlls/shell32/tests/progman_dde.c
@@ -459,8 +459,7 @@ static void test_name_sanitization(DWORD instance, HCONV hConv)
error = dde_execute(instance, hConv, buf);
ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %#x\n", error);
sprintf(buf, "Group%s", sanitized_name);
- todo_wine ok(check_exists(buf), "directory not created\n");
- if (!check_exists(buf)) return;
+ ok(check_exists(buf), "directory not created\n");
ok(check_window_exists(buf), "window not created\n");
sprintf(buf, "[ShowGroup(\"Group%s\", 0)]", original_name);
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/23
More information about the wine-devel
mailing list