shell/source/win32/SysShExec.cxx | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-)
New commits: commit af1a249be2e4403b6cfc75b1551cf038a2efb7d7 Author: Mike Kaganski <mike.kagan...@collabora.com> AuthorDate: Tue Jan 28 01:28:24 2020 +0300 Commit: Gabor Kelemen <kelem...@ubuntu.com> CommitDate: Tue Oct 26 07:16:22 2021 -0700 tdf#130216: normalize paths with .. segments ... which obviously are rejected by SHGetFileInfoW and SHParseDisplayName that it calls internally. Reviewed-on: https://gerrit.libreoffice.org/c/core/+/87565 Tested-by: Jenkins Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com> Signed-off-by: Xisco Fauli <xiscofa...@libreoffice.org> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/87737 Reviewed-by: Miklos Vajna <vmik...@collabora.com> (cherry picked from commit fc043d38c256243fb782cc48e7708feaeabba4ae) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/113087 Tested-by: Michael Stahl <michael.st...@allotropia.de> Reviewed-by: Michael Stahl <michael.st...@allotropia.de> Change-Id: I2f5f3c675ea6aa1c2d92eef30be4399a8d600255 diff --git a/shell/source/win32/SysShExec.cxx b/shell/source/win32/SysShExec.cxx index e90b68474486..26b77e826e5a 100644 --- a/shell/source/win32/SysShExec.cxx +++ b/shell/source/win32/SysShExec.cxx @@ -39,6 +39,7 @@ #endif #include <windows.h> #include <shellapi.h> +#include <Shlobj.h> #include <Shobjidl.h> #include <objbase.h> #if defined _MSC_VER @@ -307,21 +308,33 @@ void SAL_CALL CSysShExec::execute( const OUString& aCommand, const OUString& aPa + "> failed with " + OUString::number(e1)), {}, 0); } + const int MAX_LONG_PATH = 32767; // max longpath on WinNT + if (pathname.getLength() >= MAX_LONG_PATH) + { + throw css::lang::IllegalArgumentException( + "XSystemShellExecute.execute, path <" + pathname + "> too long", {}, 0); + } + wchar_t path[MAX_LONG_PATH]; + wcscpy_s(path, SAL_W(pathname.getStr())); for (int i = 0;; ++i) { + // tdf#130216: normalize c:\path\to\something\..\else into c:\path\to\else + if (PathResolve(path, nullptr, PRF_VERIFYEXISTS | PRF_REQUIREABSOLUTE) == 0) + { + throw css::lang::IllegalArgumentException( + "XSystemShellExecute.execute, PathResolve(" + OUString(SAL_U(path)) + + ") failed", + {}, 0); + } SHFILEINFOW info; - if (SHGetFileInfoW( - SAL_W(pathname.getStr()), 0, &info, sizeof info, SHGFI_EXETYPE) - != 0) + if (SHGetFileInfoW(path, 0, &info, sizeof info, SHGFI_EXETYPE) != 0) { throw css::lang::IllegalArgumentException( "XSystemShellExecute.execute, cannot process <" + aCommand + ">", {}, 0); } - if (SHGetFileInfoW( - SAL_W(pathname.getStr()), 0, &info, sizeof info, SHGFI_ATTRIBUTES) - == 0) + if (SHGetFileInfoW(path, 0, &info, sizeof info, SHGFI_ATTRIBUTES) == 0) { throw css::lang::IllegalArgumentException( - "XSystemShellExecute.execute, SHGetFileInfoW(" + pathname + ") failed", {}, + "XSystemShellExecute.execute, SHGetFileInfoW(" + OUString(SAL_U(path)) + ") failed", {}, 0); } if ((info.dwAttributes & SFGAO_LINK) == 0) { @@ -346,7 +359,7 @@ void SAL_CALL CSysShExec::execute( const OUString& aCommand, const OUString& aPa + o3tl::runtimeToOUString(e3.what())), {}, 0); } - e2 = file->Load(SAL_W(pathname.getStr()), STGM_READ); + e2 = file->Load(path, STGM_READ); if (FAILED(e2)) { throw css::lang::IllegalArgumentException( ("XSystemShellExecute.execute, IPersistFile.Load failed with " @@ -360,16 +373,15 @@ void SAL_CALL CSysShExec::execute( const OUString& aCommand, const OUString& aPa + OUString::number(e2)), {}, 0); } - wchar_t path[MAX_PATH]; WIN32_FIND_DATAW wfd; - e2 = link->GetPath(path, MAX_PATH, &wfd, SLGP_RAWPATH); + e2 = link->GetPath(path, SAL_N_ELEMENTS(path), &wfd, SLGP_RAWPATH); if (FAILED(e2)) { throw css::lang::IllegalArgumentException( ("XSystemShellExecute.execute, IShellLink.GetPath failed with " + OUString::number(e2)), {}, 0); } - pathname = SAL_U(path); + // Fail at some arbitrary nesting depth, to avoid an infinite loop: if (i == 30) { throw css::lang::IllegalArgumentException( @@ -377,7 +389,7 @@ void SAL_CALL CSysShExec::execute( const OUString& aCommand, const OUString& aPa {}, 0); } } - pathname = o3tl::toU(path); + pathname = SAL_U(path); // ShellExecuteExW appears to ignore trailing dots, so remove them: while (pathname.endsWith(".", &pathname)) {} auto const n = pathname.lastIndexOf('.');