[Libreoffice-commits] core.git: Branch 'distro/lhm/libreoffice-5-2+backports' - shell/source

Stephan Bergmann (via logerrit) logerrit at kemper.freedesktop.org
Tue Apr 30 21:44:52 UTC 2019


 shell/source/unix/exec/shellexec.cxx |   36 ++++++++++
 shell/source/win32/SysShExec.cxx     |  117 +++++++++++++++++++++++++++++++++++
 2 files changed, 153 insertions(+)

New commits:
commit bfa0f65f928e32aea98a0d639ef7ca7bf620fae3
Author:     Stephan Bergmann <sbergman at redhat.com>
AuthorDate: Fri Mar 29 14:01:19 2019 +0100
Commit:     Thorsten Behrens <Thorsten.Behrens at CIB.de>
CommitDate: Tue Apr 30 23:43:34 2019 +0200

    Filter out problematic file URLs
    
    (cherry picked from commit 7e50e885ebbe130debcd4278a10a4e288655fdfc)
    Conflicts:
            shell/source/win32/SysShExec.cxx
    
    Change-Id: I87fd37e56326bef4888354b923407530c6f70760
    Reviewed-on: https://gerrit.libreoffice.org/70188
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>
    (cherry picked from commit a35068ba25ed9da37bcb20598c9791b6979cf1ef)
    Reviewed-on: https://gerrit.libreoffice.org/71589
    Reviewed-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>
    Tested-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>

diff --git a/shell/source/unix/exec/shellexec.cxx b/shell/source/unix/exec/shellexec.cxx
index 7f12a80b76ef..857e0b1ec90c 100644
--- a/shell/source/unix/exec/shellexec.cxx
+++ b/shell/source/unix/exec/shellexec.cxx
@@ -42,6 +42,9 @@
 #include <errno.h>
 #include <unistd.h>
 
+#if defined MACOSX
+#include <sys/stat.h>
+#endif
 
 // namespace directives
 
@@ -129,6 +132,39 @@ void SAL_CALL ShellExec::execute( const OUString& aCommand, const OUString& aPar
         }
 
 #ifdef MACOSX
+        if (uri->getScheme().equalsIgnoreAsciiCase("file")) {
+            OUString pathname;
+            auto const e1 = osl::FileBase::getSystemPathFromFileURL(aCommand, pathname);
+            if (e1 != osl::FileBase::E_None) {
+                throw css::lang::IllegalArgumentException(
+                    ("XSystemShellExecute.execute, getSystemPathFromFileURL <" + aCommand
+                     + "> failed with " + OUString::number(e1)),
+                    {}, 0);
+            }
+            OString pathname8;
+            if (!pathname.convertToString(
+                    &pathname8, RTL_TEXTENCODING_UTF8,
+                    (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR
+                     | RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR)))
+            {
+                throw css::lang::IllegalArgumentException(
+                    "XSystemShellExecute.execute, cannot convert \"" + pathname + "\" to UTF-8", {},
+                    0);
+            }
+            struct stat st;
+            auto const e2 = stat(pathname8.getStr(), &st);
+            if (e2 != 0) {
+                auto const e3 = errno;
+                SAL_INFO("shell", "stat(" << pathname8 << ") failed with errno " << e3);
+            }
+            if (e2 != 0 || !S_ISREG(st.st_mode)
+                || (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)) != 0)
+            {
+                throw css::lang::IllegalArgumentException(
+                    "XSystemShellExecute.execute, cannot process <" + aCommand + ">", {}, 0);
+            }
+        }
+
         //TODO: Using open(1) with an argument that syntactically is an absolute
         // URI reference does not necessarily give expected results:
         // 1  If the given URI reference matches a supported scheme (e.g.,
diff --git a/shell/source/win32/SysShExec.cxx b/shell/source/win32/SysShExec.cxx
index 70c694749b66..3c577df58510 100644
--- a/shell/source/win32/SysShExec.cxx
+++ b/shell/source/win32/SysShExec.cxx
@@ -18,8 +18,11 @@
  */
 
 #include <algorithm>
+#include <cassert>
 
 #include <osl/diagnose.h>
+#include <osl/process.h>
+#include <sal/log.hxx>
 #include "SysShExec.hxx"
 #include <osl/file.hxx>
 #include <sal/macros.h>
@@ -27,6 +30,7 @@
 #include <com/sun/star/system/SystemShellExecuteFlags.hpp>
 #include <com/sun/star/uri/UriReferenceFactory.hpp>
 #include <cppuhelper/supportsservice.hxx>
+#include <o3tl/runtimetooustring.hxx>
 
 #define WIN32_LEAN_AND_MEAN
 #if defined _MSC_VER
@@ -34,6 +38,7 @@
 #endif
 #include <windows.h>
 #include <shellapi.h>
+#include <Shobjidl.h>
 #include <objbase.h>
 #if defined _MSC_VER
 #pragma warning(pop)
@@ -43,6 +48,8 @@
 // namespace directives
 
 
+#include <systools/win32/comtools.hxx>
+
 using com::sun::star::uno::Reference;
 using com::sun::star::uno::RuntimeException;
 using com::sun::star::uno::Sequence;
@@ -252,6 +259,20 @@ CSysShExec::CSysShExec( const Reference< css::uno::XComponentContext >& xContext
     CoInitialize( NULL );
 }
 
+namespace
+{
+bool checkExtension(OUString const & extension, OUString const & blacklist) {
+    assert(!extension.isEmpty());
+    for (sal_Int32 i = 0; i != -1;) {
+        OUString tok = blacklist.getToken(0, ';', i);
+        tok.startsWith(".", &tok);
+        if (extension.equalsIgnoreAsciiCase(tok)) {
+            return false;
+        }
+    }
+    return true;
+}
+}
 
 void SAL_CALL CSysShExec::execute( const OUString& aCommand, const OUString& aParameter, sal_Int32 nFlags )
         throw (IllegalArgumentException, SystemShellExecuteException, RuntimeException)
@@ -281,6 +302,102 @@ void SAL_CALL CSysShExec::execute( const OUString& aCommand, const OUString& aPa
                  + aCommand,
                 static_cast< cppu::OWeakObject * >(this), 0);
         }
+        if (uri->getScheme().equalsIgnoreAsciiCase("file")) {
+            OUString pathname;
+            auto const e1 = osl::FileBase::getSystemPathFromFileURL(aCommand, pathname);
+            if (e1 != osl::FileBase::E_None) {
+                throw css::lang::IllegalArgumentException(
+                    ("XSystemShellExecute.execute, getSystemPathFromFileURL <" + aCommand
+                     + "> failed with " + OUString::number(e1)),
+                    {}, 0);
+            }
+            for (int i = 0;; ++i) {
+                SHFILEINFOW info;
+                if (SHGetFileInfoW(
+                        pathname.getStr(), 0, &info, sizeof info, SHGFI_EXETYPE)
+                    != 0)
+                {
+                    throw css::lang::IllegalArgumentException(
+                        "XSystemShellExecute.execute, cannot process <" + aCommand + ">", {}, 0);
+                }
+                if (SHGetFileInfoW(
+                        pathname.getStr(), 0, &info, sizeof info, SHGFI_ATTRIBUTES)
+                    == 0)
+                {
+                    throw css::lang::IllegalArgumentException(
+                        "XSystemShellExecute.execute, SHGetFileInfoW(" + pathname + ") failed", {},
+                        0);
+                }
+                if ((info.dwAttributes & SFGAO_LINK) == 0) {
+                    break;
+                }
+                sal::systools::COMReference<IShellLinkW> link;
+                auto e2 = CoCreateInstance(
+                    CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER, IID_IShellLinkW,
+                    reinterpret_cast<LPVOID *>(&link));
+                if (FAILED(e2)) {
+                    throw css::lang::IllegalArgumentException(
+                        ("XSystemShellExecute.execute, CoCreateInstance failed with "
+                         + OUString::number(e2)),
+                        {}, 0);
+                }
+                sal::systools::COMReference<IPersistFile> file;
+                try {
+                    file = link.QueryInterface<IPersistFile>(IID_IPersistFile);
+                } catch(sal::systools::ComError & e3) {
+                    throw css::lang::IllegalArgumentException(
+                        ("XSystemShellExecute.execute, QueryInterface failed with: "
+                         + o3tl::runtimeToOUString(e3.what())),
+                        {}, 0);
+                }
+                e2 = file->Load(pathname.getStr(), STGM_READ);
+                if (FAILED(e2)) {
+                    throw css::lang::IllegalArgumentException(
+                        ("XSystemShellExecute.execute, IPersistFile.Load failed with "
+                         + OUString::number(e2)),
+                        {}, 0);
+                }
+                e2 = link->Resolve(nullptr, SLR_UPDATE | SLR_NO_UI);
+                if (FAILED(e2)) {
+                    throw css::lang::IllegalArgumentException(
+                        ("XSystemShellExecute.execute, IShellLink.Resolve failed with "
+                         + OUString::number(e2)),
+                        {}, 0);
+                }
+                wchar_t path[MAX_PATH];
+                WIN32_FIND_DATAW wfd;
+                e2 = link->GetPath(path, MAX_PATH, &wfd, SLGP_RAWPATH);
+                if (FAILED(e2)) {
+                    throw css::lang::IllegalArgumentException(
+                        ("XSystemShellExecute.execute, IShellLink.GetPath failed with "
+                         + OUString::number(e2)),
+                        {}, 0);
+                }
+                pathname = path;
+                // Fail at some arbitrary nesting depth, to avoid an infinite loop:
+                if (i == 30) {
+                    throw css::lang::IllegalArgumentException(
+                        "XSystemShellExecute.execute, link depth exceeded for <" + aCommand + ">",
+                        {}, 0);
+                }
+            }
+            auto const n = pathname.lastIndexOf('.');
+            if (n > pathname.lastIndexOf('\\')) {
+                auto const ext = pathname.copy(n + 1);
+                OUString env;
+                if (osl_getEnvironment(OUString("PATHEXT").pData, &env.pData) != osl_Process_E_None)
+                {
+                    SAL_INFO("shell", "osl_getEnvironment(PATHEXT) failed");
+                }
+                if (!(checkExtension(ext, env)
+                      && checkExtension(
+                          ext, ".COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC;.PY")))
+                {
+                    throw css::lang::IllegalArgumentException(
+                        "XSystemShellExecute.execute, cannot process <" + aCommand + ">", {}, 0);
+                }
+            }
+        }
     }
 
     /*  #i4789#; jump mark detection on system paths


More information about the Libreoffice-commits mailing list