Kaydet (Commit) d59ec4cd authored tarafından Stephan Bergmann's avatar Stephan Bergmann

Filter out problematic file URLs

Change-Id: I87fd37e56326bef4888354b923407530c6f70760
Reviewed-on: https://gerrit.libreoffice.org/70177
Tested-by: Jenkins
Reviewed-by: 's avatarStephan Bergmann <sbergman@redhat.com>
üst 3b41abe6
......@@ -43,6 +43,10 @@
#include <errno.h>
#include <unistd.h>
#if defined MACOSX
#include <sys/stat.h>
#endif
using com::sun::star::system::XSystemShellExecute;
using com::sun::star::system::SystemShellExecuteException;
......@@ -113,6 +117,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.,
......
......@@ -18,8 +18,10 @@
*/
#include <algorithm>
#include <cassert>
#include <osl/diagnose.h>
#include <osl/process.h>
#include <sal/log.hxx>
#include "SysShExec.hxx"
#include <osl/file.hxx>
......@@ -30,12 +32,16 @@
#include <com/sun/star/uri/UriReferenceFactory.hpp>
#include <cppuhelper/supportsservice.hxx>
#include <o3tl/char16_t2wchar_t.hxx>
#include <o3tl/runtimetooustring.hxx>
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <shellapi.h>
#include <Shobjidl.h>
#include <objbase.h>
#include <systools/win32/comtools.hxx>
using com::sun::star::uno::Reference;
using com::sun::star::uno::RuntimeException;
using com::sun::star::uno::Sequence;
......@@ -242,6 +248,18 @@ CSysShExec::CSysShExec( const Reference< css::uno::XComponentContext >& xContext
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;
}
// This callback checks if the found window is the specified process's top-level window,
// and activates the first found such window.
BOOL CALLBACK FindAndActivateProcWnd(HWND hwnd, LPARAM lParam)
......@@ -295,6 +313,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(
o3tl::toW(pathname.getStr()), 0, &info, sizeof info, SHGFI_EXETYPE)
!= 0)
{
throw css::lang::IllegalArgumentException(
"XSystemShellExecute.execute, cannot process <" + aCommand + ">", {}, 0);
}
if (SHGetFileInfoW(
o3tl::toW(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(o3tl::toW(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 = o3tl::toU(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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment