From: Nikolay Sivov Subject: shell32: Validate folder id passed to Namespace() Message-Id: <556190CE.8050707@codeweavers.com> Date: Sun, 24 May 2015 11:50:22 +0300 --- From 72b993ee72cd001a94527ce7af0574df8c0e9b7d Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Sat, 23 May 2015 18:24:33 +0300 Subject: [PATCH] shell32: Validate folder id passed to Namespace() --- dlls/shell32/shelldispatch.c | 70 +++++++++++++++++++++++++++++++++++++- dlls/shell32/tests/shelldispatch.c | 18 ++++++++-- include/shldisp.idl | 3 +- 3 files changed, 87 insertions(+), 4 deletions(-) diff --git a/dlls/shell32/shelldispatch.c b/dlls/shell32/shelldispatch.c index 5b8266b..3cf1293 100644 --- a/dlls/shell32/shelldispatch.c +++ b/dlls/shell32/shelldispatch.c @@ -1246,6 +1246,73 @@ static const Folder3Vtbl FolderImpl_Vtbl = { FolderImpl_put_ShowWebViewBarricade }; +static BOOL is_valid_folderid(int id) +{ + switch (id) + { + case CSIDL_DESKTOP: + case CSIDL_INTERNET: + case CSIDL_PROGRAMS: + case CSIDL_CONTROLS: + case CSIDL_PRINTERS: + case CSIDL_PERSONAL: + case CSIDL_FAVORITES: + case CSIDL_STARTUP: + case CSIDL_RECENT: + case CSIDL_SENDTO: + case CSIDL_BITBUCKET: + case CSIDL_STARTMENU: + case CSIDL_MYMUSIC: + case CSIDL_MYVIDEO: + case CSIDL_DESKTOPDIRECTORY: + case CSIDL_DRIVES: + case CSIDL_NETWORK: + case CSIDL_NETHOOD: + case CSIDL_FONTS: + case CSIDL_TEMPLATES: + case CSIDL_COMMON_STARTMENU: + case CSIDL_COMMON_PROGRAMS: + case CSIDL_COMMON_STARTUP: + case CSIDL_COMMON_DESKTOPDIRECTORY: + case CSIDL_APPDATA: + case CSIDL_PRINTHOOD: + case CSIDL_LOCAL_APPDATA: + case CSIDL_ALTSTARTUP: + case CSIDL_COMMON_ALTSTARTUP: + case CSIDL_COMMON_FAVORITES: + case CSIDL_INTERNET_CACHE: + case CSIDL_COOKIES: + case CSIDL_HISTORY: + case CSIDL_COMMON_APPDATA: + case CSIDL_WINDOWS: + case CSIDL_SYSTEM: + case CSIDL_PROGRAM_FILES: + case CSIDL_MYPICTURES: + case CSIDL_PROFILE: + case CSIDL_SYSTEMX86: + case CSIDL_PROGRAM_FILESX86: + case CSIDL_PROGRAM_FILES_COMMON: + case CSIDL_PROGRAM_FILES_COMMONX86: + case CSIDL_COMMON_TEMPLATES: + case CSIDL_COMMON_DOCUMENTS: + case CSIDL_COMMON_ADMINTOOLS: + case CSIDL_ADMINTOOLS: + case CSIDL_CONNECTIONS: + case CSIDL_COMMON_MUSIC: + case CSIDL_COMMON_PICTURES: + case CSIDL_COMMON_VIDEO: + case CSIDL_RESOURCES: + case CSIDL_RESOURCES_LOCALIZED: + case CSIDL_COMMON_OEM_LINKS: + case CSIDL_CDBURN_AREA: + case CSIDL_COMPUTERSNEARME: + return TRUE; + default: + WARN("unsupported folder id %d\n", id); + return FALSE; + } +} + static HRESULT Folder_Constructor(VARIANT *dir, Folder **ppsdf) { FolderImpl *This; @@ -1256,7 +1323,8 @@ static HRESULT Folder_Constructor(VARIANT *dir, Folder **ppsdf) switch (V_VT(dir)) { case VT_I4: - /* FIXME: add some checks */ + if (!is_valid_folderid(V_I4(dir))) + return S_FALSE; break; case VT_BSTR: if (PathIsDirectoryW(V_BSTR(dir)) && diff --git a/dlls/shell32/tests/shelldispatch.c b/dlls/shell32/tests/shelldispatch.c index f9d92ee..2b37e0e 100644 --- a/dlls/shell32/tests/shelldispatch.c +++ b/dlls/shell32/tests/shelldispatch.c @@ -86,14 +86,28 @@ static void test_namespace(void) ok(r == S_FALSE, "expected S_FALSE, got %08x\n", r); ok(folder == NULL, "expected NULL, got %p\n", folder); + /* NameSpace() works for all CSIDL_* indices up to CSIDL_COMPUTERNEARME */ + V_VT(&var) = VT_I4; + V_I4(&var) = CSIDL_COMPUTERSNEARME; + folder = NULL; + r = IShellDispatch_NameSpace(sd, var, &folder); + ok(r == S_OK, "got %08x\n", r); + Folder_Release(folder); + + V_VT(&var) = VT_I4; + V_I4(&var) = CSIDL_PROFILES; + folder = (void*)0xdeadbeef; + r = IShellDispatch_NameSpace(sd, var, &folder); + ok(r == S_FALSE, "expected S_FALSE, got %08x\n", r); + ok(folder == NULL, "expected NULL, got %p\n", folder); + V_VT(&var) = VT_I4; V_I4(&var) = -1; folder = (void*)0xdeadbeef; r = IShellDispatch_NameSpace(sd, var, &folder); - todo_wine { ok(r == S_FALSE, "expected S_FALSE, got %08x\n", r); ok(folder == NULL, "got %p\n", folder); -} + V_VT(&var) = VT_I4; V_I4(&var) = ssfPROGRAMFILES; r = IShellDispatch_NameSpace(sd, var, &folder); diff --git a/include/shldisp.idl b/include/shldisp.idl index 56be778..51b3ce1 100644 --- a/include/shldisp.idl +++ b/include/shldisp.idl @@ -589,7 +589,8 @@ enum ShellSpecialFolderConstants { ssfMYPICTURES = 0x27, ssfPROFILE = 0x28, ssfSYSTEMx86 = 0x29, - ssfPROGRAMFILESx86 = 0x30 + ssfPROGRAMFILESx86 = 0x30 /* This doesn't match CSIDL_PROGRAM_FILESX86 value, and + instead works as CSIDL_ADMINTOOLS. Most likely a typo. */ } ShellSpecialFolderConstants; /***************************************************************************** -- 2.1.4