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('.');

Reply via email to