include/o3tl/runtimetooustring.hxx | 48 ++++++++++++++ shell/source/unix/exec/shellexec.cxx | 36 ++++++++++ shell/source/win32/SysShExec.cxx | 117 +++++++++++++++++++++++++++++++++++ 3 files changed, 201 insertions(+)
New commits: commit 9f8aeee1c9fb6dbccde1e945861f82f44e2bdc1e Author: Stephan Bergmann <sberg...@redhat.com> AuthorDate: Fri Mar 29 14:01:19 2019 +0100 Commit: Michael Stahl <michael.st...@cib.de> CommitDate: Thu May 2 11:24:36 2019 +0200 Filter out problematic file URLs (cherry picked from commit 7e50e885ebbe130debcd4278a10a4e288655fdfc) Conflicts: shell/source/win32/SysShExec.cxx Reviewed-on: https://gerrit.libreoffice.org/70188 Tested-by: Jenkins Reviewed-by: Caolán McNamara <caol...@redhat.com> Tested-by: Caolán McNamara <caol...@redhat.com> (cherry picked from commit a35068ba25ed9da37bcb20598c9791b6979cf1ef) Change-Id: I87fd37e56326bef4888354b923407530c6f70760 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 55cbb90a5782..44a6e047bdc6 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 commit a43be858b701d1d80a80659623c396f9098a770c Author: Stephan Bergmann <sberg...@redhat.com> AuthorDate: Wed Nov 23 23:10:29 2016 +0100 Commit: Michael Stahl <michael.st...@cib.de> CommitDate: Thu May 2 11:21:24 2019 +0200 New o3tl::runtimeToOUString to convert from C++ runtime NTBS to OUString Change-Id: I613bb70b6828f615fd45af38b2d873ece55ace60 (cherry picked from commit d689ad29c28ad7f077c2239a8fa4c2b6307a6aa1) Reviewed-on: https://gerrit.libreoffice.org/71591 Reviewed-by: Michael Stahl <michael.st...@cib.de> Tested-by: Michael Stahl <michael.st...@cib.de> diff --git a/include/o3tl/runtimetooustring.hxx b/include/o3tl/runtimetooustring.hxx new file mode 100644 index 000000000000..7f2015805722 --- /dev/null +++ b/include/o3tl/runtimetooustring.hxx @@ -0,0 +1,48 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef INCLUDED_O3TL_RUNTIMETOOUSTRING_HXX +#define INCLUDED_O3TL_RUNTIMETOOUSTRING_HXX + +#include <sal/config.h> + +#include <cassert> +#include <cstring> + +#include <rtl/textcvt.h> +#include <rtl/textenc.h> +#include <rtl/ustring.h> +#include <rtl/ustring.hxx> + +namespace o3tl { + +/** Convert an NTBS from the C++ runtime to an OUString. + + This is used to convert an NTBS as provided by std::exception::what or + std::type_info::name into an OUString in a "lossless" way. The conversion + is done using RTL_TEXTENCODING_ISO_8859_1, so each char in the input maps + to one Unicode character in the output. +*/ +inline OUString runtimeToOUString(char const * runtimeString) { + OUString s; + bool ok = rtl_convertStringToUString( + &s.pData, runtimeString, std::strlen(runtimeString), + RTL_TEXTENCODING_ISO_8859_1, + (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR + | RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR + | RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR)); + assert(ok); (void) ok; + return s; +} + +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits