From cde7dc6117d4033c1fb590341f304755a55f764c Mon Sep 17 00:00:00 2001 From: Samuel Mehrbrodt Date: Tue, 16 Mar 2021 16:27:44 +0100 Subject: Add mechanism to selectively enable macros for document events Change-Id: I56703b2c0ee009a645458c78c026c546b2e7e321 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/112584 Tested-by: Jenkins Reviewed-by: Samuel Mehrbrodt (cherry picked from commit 0a893a15b02a3662e3c68776be09534c9f955e4f) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/114436 Tested-by: Thorsten Behrens Reviewed-by: Thorsten Behrens Reviewed-on: https://gerrit.libreoffice.org/c/core/+/114706 --- .../schema/org/openoffice/Office/Common.xcs | 22 ++++++++++++++ sfx2/Library_sfx.mk | 3 ++ sfx2/source/inc/eventsupplier.hxx | 4 +++ sfx2/source/notify/eventsupplier.cxx | 34 ++++++++++++++++++++++ 4 files changed, 63 insertions(+) diff --git a/officecfg/registry/schema/org/openoffice/Office/Common.xcs b/officecfg/registry/schema/org/openoffice/Office/Common.xcs index 7c0eb6c255d2..b317f616deeb 100644 --- a/officecfg/registry/schema/org/openoffice/Office/Common.xcs +++ b/officecfg/registry/schema/org/openoffice/Office/Common.xcs @@ -2708,6 +2708,28 @@ false + + + Warn on load when a document binds an event to a macro + + true + + + + List of script URLS which are allowed to be called by document events. + Look into content.xml of the odf file to find the URL. + You can either write the full URL, a part of it (starting from the beginning), + or use regular expressions. + Examples: + * vnd.sun.star.script:Standard.Module1.Main?language=Basic&location=user + * vnd.sun.star.script:Standard.Module1 + * vnd.sun.star.script:YourScript.*location=share + * .*location=application.* + + When this list is empty, all document event URLs are allowed. + + + List with trusted authors. diff --git a/sfx2/Library_sfx.mk b/sfx2/Library_sfx.mk index 8f386caaa283..bf1dbea7b3c3 100644 --- a/sfx2/Library_sfx.mk +++ b/sfx2/Library_sfx.mk @@ -69,6 +69,9 @@ $(eval $(call gb_Library_use_libraries,sfx,\ $(eval $(call gb_Library_use_externals,sfx,\ boost_headers \ + icu_headers \ + icui18n \ + icuuc \ libxml2 \ orcus \ orcus-parser\ diff --git a/sfx2/source/inc/eventsupplier.hxx b/sfx2/source/inc/eventsupplier.hxx index be6421416939..4624ed8b4907 100644 --- a/sfx2/source/inc/eventsupplier.hxx +++ b/sfx2/source/inc/eventsupplier.hxx @@ -86,6 +86,10 @@ public: ::comphelper::NamedValueCollection& o_normalizedDescriptor, SfxObjectShell* i_document ); static void Execute( css::uno::Any const & aEventData, const css::document::DocumentEvent& aTrigger, SfxObjectShell* pDoc ); + +private: + /// Check if script URL whitelist exists, and if so, if current script url is part of it + static bool isScriptURLAllowed(const OUString& aScriptURL); }; #endif diff --git a/sfx2/source/notify/eventsupplier.cxx b/sfx2/source/notify/eventsupplier.cxx index e21130d6022c..12bf1ce828e5 100644 --- a/sfx2/source/notify/eventsupplier.cxx +++ b/sfx2/source/notify/eventsupplier.cxx @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -39,6 +40,7 @@ #include #include #include +#include #include #include @@ -49,6 +51,10 @@ #include #include +#include +#include +#include + using namespace css; using namespace ::com::sun::star; @@ -178,6 +184,31 @@ namespace } } +bool SfxEvents_Impl::isScriptURLAllowed(const OUString& aScriptURL) +{ + boost::optional> allowedEvents( + officecfg::Office::Common::Security::Scripting::AllowedDocumentEventURLs::get()); + // When AllowedDocumentEventURLs is empty, all event URLs are allowed + if (!allowedEvents) + return true; + + icu::ErrorCode status; + const uint32_t rMatcherFlags = UREGEX_CASE_INSENSITIVE; + icu::UnicodeString usInput(aScriptURL.getStr()); + const css::uno::Sequence& rAllowedEvents = *allowedEvents; + for (auto const& allowedEvent : rAllowedEvents) + { + icu::UnicodeString usRegex(allowedEvent.getStr()); + icu::RegexMatcher rmatch1(usRegex, usInput, rMatcherFlags, status); + if (aScriptURL.startsWith(allowedEvent) || rmatch1.matches(status)) + { + return true; + } + } + + return false; +} + void SfxEvents_Impl::Execute( uno::Any const & aEventData, const document::DocumentEvent& aTrigger, SfxObjectShell* pDoc ) { uno::Sequence < beans::PropertyValue > aProperties; @@ -216,6 +247,9 @@ void SfxEvents_Impl::Execute( uno::Any const & aEventData, const document::Docum if (aScript.isEmpty()) return; + if (!isScriptURLAllowed(aScript)) + return; + if (!pDoc) pDoc = SfxObjectShell::Current(); -- cgit