From: Caolán McNamara Date: Wed, 7 Aug 2019 16:37:11 +0000 (+0100) Subject: CVE-2022-3140: warn on load when a document binds an event to a macro X-Git-Tag: archive/raspbian/1%6.1.5-3+rpi1+deb10u10^2~10 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=0c1acd8266dd610e8fd3a101cadd69ee908d3f85;p=libreoffice.git CVE-2022-3140: warn on load when a document binds an event to a macro a) treat shared/Scripts equivalently to document scripts This doesn't automatically warn/block running those scripts when used in a freshly loaded document on its own however because DocumentMacroMode::checkMacrosOnLoading will see at... if ( m_xData->m_rDocumentAccess.documentStorageHasMacros() || hasMacroLibrary() ) that the document contains no macros and flip the allow macros flag to true so that potentially new uses of macros added by the user during the edit are allowed to run b) so, add an additional flag to indicate existence of use of macros in a document c) for odf import, set it when a script:event-listener tag is encountered d) for html import when registerScriptEvents or SwFormatINetFormat::SetMacroTable is called e) for doc import when Read_F_Macro or StoreMacroCmds is called as well for good measure f) for xls import when registerScriptEvent or ScMacroInfo::SetMacro is called g) for oox import when VbaProject::attachMacros is called Reviewed-on: https://gerrit.libreoffice.org/77387 Tested-by: Jenkins Reviewed-by: Christian Lohmaier (cherry picked from commit 35fe064a67b54b0680b4845477c9b8751edda160) Change-Id: Ic1203d8ec7dfc217aa217135033ae9db2888e19b Reviewed-on: https://gerrit.libreoffice.org/83348 Reviewed-by: Thorsten Behrens Tested-by: Thorsten Behrens origin: https://github.com/LibreOffice/core/commit/96b7887cbfd24bb29e08667b027a86f79c246ce2 bug-debian-security: https://deb.freexian.com/extended-lts/tracker/CVE-2022-3140 bug: https://deb.freexian.com/extended-lts/tracker/CVE-2022-3140 Gbp-Pq: Name 0071-CVE-2022-3140-warn-on-load-when-a-document-binds-an-.patch --- diff --git a/comphelper/source/misc/documentinfo.cxx b/comphelper/source/misc/documentinfo.cxx index b6345059055..f0d2840d922 100644 --- a/comphelper/source/misc/documentinfo.cxx +++ b/comphelper/source/misc/documentinfo.cxx @@ -157,6 +157,20 @@ namespace comphelper { return sTitle; } + void DocumentInfo::notifyMacroEventRead(const css::uno::Reference& rModel) + { + if (!rModel.is()) + return; + + // like BreakMacroSignature of XMLScriptContext use XModel::attachResource + // to propagate this notification + css::uno::Sequence aMedDescr = rModel->getArgs(); + sal_Int32 nNewLen = aMedDescr.getLength() + 1; + aMedDescr.realloc(nNewLen); + aMedDescr[nNewLen-1].Name = "MacroEventRead"; + aMedDescr[nNewLen-1].Value <<= true; + rModel->attachResource(rModel->getURL(), aMedDescr); + } } // namespace comphelper diff --git a/dbaccess/source/core/dataaccess/ModelImpl.cxx b/dbaccess/source/core/dataaccess/ModelImpl.cxx index af71c72510c..3281d0dd2b7 100644 --- a/dbaccess/source/core/dataaccess/ModelImpl.cxx +++ b/dbaccess/source/core/dataaccess/ModelImpl.cxx @@ -376,6 +376,7 @@ ODatabaseModelImpl::ODatabaseModelImpl( const Reference< XComponentContext >& _r ,m_bSuppressVersionColumns(true) ,m_bModified(false) ,m_bDocumentReadOnly(false) + ,m_bMacroCallsSeenWhileLoading(false) ,m_pSharedConnectionManager(nullptr) ,m_nControllerLockCount(0) { @@ -409,6 +410,7 @@ ODatabaseModelImpl::ODatabaseModelImpl( ,m_bSuppressVersionColumns(true) ,m_bModified(false) ,m_bDocumentReadOnly(false) + ,m_bMacroCallsSeenWhileLoading(false) ,m_pSharedConnectionManager(nullptr) ,m_nControllerLockCount(0) { @@ -1274,6 +1276,11 @@ bool ODatabaseModelImpl::documentStorageHasMacros() const return ( *m_aEmbeddedMacros != eNoMacros ); } +bool ODatabaseModelImpl::macroCallsSeenWhileLoading() const +{ + return m_bMacroCallsSeenWhileLoading; +} + Reference< XEmbeddedScripts > ODatabaseModelImpl::getEmbeddedDocumentScripts() const { return Reference< XEmbeddedScripts >( getModel_noCreate(), UNO_QUERY ); diff --git a/dbaccess/source/core/dataaccess/databasedocument.cxx b/dbaccess/source/core/dataaccess/databasedocument.cxx index eee5e846503..eb20c56ed84 100644 --- a/dbaccess/source/core/dataaccess/databasedocument.cxx +++ b/dbaccess/source/core/dataaccess/databasedocument.cxx @@ -744,15 +744,24 @@ sal_Bool SAL_CALL ODatabaseDocument::attachResource( const OUString& _rURL, cons bool ODatabaseDocument::impl_attachResource( const OUString& i_rLogicalDocumentURL, const Sequence< PropertyValue >& i_rMediaDescriptor, DocumentGuard& _rDocGuard ) { - if ( ( i_rLogicalDocumentURL == getURL() ) - && ( i_rMediaDescriptor.getLength() == 1 ) - && ( i_rMediaDescriptor[0].Name == "BreakMacroSignature" ) - ) + if (i_rLogicalDocumentURL == getURL()) { - // this is a BAD hack of the Basic importer code ... there should be a dedicated API for this, - // not this bad mis-using of existing interfaces - return false; - // (we do not support macro signatures, so we can ignore this call) + ::comphelper::NamedValueCollection aArgs(i_rMediaDescriptor); + + // this misuse of attachresource is a hack of the Basic importer code + // repurposing existing interfaces for uses it probably wasn't intended + // for + + // we do not support macro signatures, so we can ignore that request + aArgs.remove("BreakMacroSignature"); + + bool bMacroEventRead = false; + if ((aArgs.get( "MacroEventRead" ) >>= bMacroEventRead) && bMacroEventRead) + m_pImpl->m_bMacroCallsSeenWhileLoading = true; + aArgs.remove( "MacroEventRead" ); + + if (aArgs.empty()) + return false; } // if no URL has been provided, the caller was lazy enough to not call our getURL - which is not allowed anymore, diff --git a/dbaccess/source/core/inc/ModelImpl.hxx b/dbaccess/source/core/inc/ModelImpl.hxx index 4a763c57791..d7a642a0239 100644 --- a/dbaccess/source/core/inc/ModelImpl.hxx +++ b/dbaccess/source/core/inc/ModelImpl.hxx @@ -208,6 +208,7 @@ public: bool m_bSuppressVersionColumns : 1; bool m_bModified : 1; bool m_bDocumentReadOnly : 1; + bool m_bMacroCallsSeenWhileLoading : 1; css::uno::Reference< css::beans::XPropertyBag > m_xSettings; css::uno::Sequence< OUString > m_aTableFilter; @@ -436,6 +437,7 @@ public: virtual void setCurrentMacroExecMode( sal_uInt16 ) override; virtual OUString getDocumentLocation() const override; virtual bool documentStorageHasMacros() const override; + virtual bool macroCallsSeenWhileLoading() const override; virtual css::uno::Reference< css::document::XEmbeddedScripts > getEmbeddedDocumentScripts() const override; virtual SignatureState getScriptingSignatureState() override; virtual bool hasTrustedScriptingSignature( bool bAllowUIToAddAuthor ) override; diff --git a/include/comphelper/documentinfo.hxx b/include/comphelper/documentinfo.hxx index c30d79b40c9..e9c2b153885 100644 --- a/include/comphelper/documentinfo.hxx +++ b/include/comphelper/documentinfo.hxx @@ -35,8 +35,11 @@ namespace comphelper { /** retrieves the UI title of the given document */ COMPHELPER_DLLPUBLIC OUString getDocumentTitle( const css::uno::Reference< css::frame::XModel >& _rxDocument ); - } + /** notify that this document contains a macro event handler + */ + COMPHELPER_DLLPUBLIC void notifyMacroEventRead( const css::uno::Reference< css::frame::XModel >& _rxDocument ); + } } // namespace comphelper diff --git a/include/oox/ole/axcontrol.hxx b/include/oox/ole/axcontrol.hxx index a932a7bcfcd..434c0c43c49 100644 --- a/include/oox/ole/axcontrol.hxx +++ b/include/oox/ole/axcontrol.hxx @@ -334,6 +334,8 @@ public: PropertySet const & rPropSet, sal_Int32& nOrientation ); + const css::uno::Reference GetDocModel() const { return mxDocModel; } + private: css::uno::Reference< css::frame::XModel > mxDocModel; const GraphicHelper& mrGraphicHelper; diff --git a/include/sfx2/docmacromode.hxx b/include/sfx2/docmacromode.hxx index f043e36a26d..7e151162508 100644 --- a/include/sfx2/docmacromode.hxx +++ b/include/sfx2/docmacromode.hxx @@ -111,6 +111,12 @@ namespace sfx2 virtual bool documentStorageHasMacros() const = 0; + /** checks whether the document's contained calls to macros or scripts after loading + + */ + virtual bool + macroCallsSeenWhileLoading() const = 0; + /** provides access to the XEmbeddedScripts interface of the document Implementations are allowed to return here if and only if they @@ -272,6 +278,7 @@ namespace sfx2 @see isMacroExecutionDisallowed @see IMacroDocumentAccess::documentStorageHasMacros + @see IMacroDocumentAccess::macroCallsSeenWhileLoading @see hasMacroLibrary @see IMacroDocumentAccess::checkForBrokenScriptingSignatures */ diff --git a/include/sfx2/objsh.hxx b/include/sfx2/objsh.hxx index ed09fc6e2ac..83033e57ed7 100644 --- a/include/sfx2/objsh.hxx +++ b/include/sfx2/objsh.hxx @@ -426,6 +426,9 @@ public: sal_uInt32 GetModifyPasswordHash() const; bool SetModifyPasswordHash( sal_uInt32 nHash ); + void SetMacroCallsSeenWhileLoading(); + bool GetMacroCallsSeenWhileLoading() const; + const css::uno::Sequence< css::beans::PropertyValue >& GetModifyPasswordInfo() const; bool SetModifyPasswordInfo( const css::uno::Sequence< css::beans::PropertyValue >& aInfo ); diff --git a/include/xmloff/xmlimp.hxx b/include/xmloff/xmlimp.hxx index f213f21cd2f..cfdd00bb045 100644 --- a/include/xmloff/xmlimp.hxx +++ b/include/xmloff/xmlimp.hxx @@ -241,6 +241,7 @@ class XMLOFF_DLLPUBLIC SvXMLImport : public cppu::WeakImplHelper< protected: bool mbIsFormsSupported; bool mbIsTableShapeSupported; + bool mbNotifyMacroEventRead; // Create top-level element context. // This method is called after the namespace map has been updated, but @@ -577,6 +578,8 @@ public: bool embeddedFontAlreadyProcessed( const OUString& url ); virtual void NotifyEmbeddedFontRead() {}; + // something referencing a macro/script was imported + void NotifyMacroEventRead(); bool needFixPositionAfterZ() const; }; diff --git a/oox/source/ole/vbaproject.cxx b/oox/source/ole/vbaproject.cxx index 5a779944e0e..f7ae54fa2a4 100644 --- a/oox/source/ole/vbaproject.cxx +++ b/oox/source/ole/vbaproject.cxx @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -515,6 +516,8 @@ void VbaProject::attachMacros() { if( !maMacroAttachers.empty() && mxContext.is() ) try { + comphelper::DocumentInfo::notifyMacroEventRead(mxDocModel); + Reference< XMultiComponentFactory > xFactory( mxContext->getServiceManager(), UNO_SET_THROW ); Sequence< Any > aArgs( 2 ); aArgs[ 0 ] <<= mxDocModel; @@ -522,6 +525,7 @@ void VbaProject::attachMacros() Reference< XVBAMacroResolver > xResolver( xFactory->createInstanceWithArgumentsAndContext( "com.sun.star.script.vba.VBAMacroResolver", aArgs, mxContext ), UNO_QUERY_THROW ); maMacroAttachers.forEachMem( &VbaMacroAttacherBase::resolveAndAttachMacro, ::std::cref( xResolver ) ); + } catch(const Exception& ) { diff --git a/sc/source/filter/excel/xiescher.cxx b/sc/source/filter/excel/xiescher.cxx index c41afaa1c08..a58d8ece620 100644 --- a/sc/source/filter/excel/xiescher.cxx +++ b/sc/source/filter/excel/xiescher.cxx @@ -48,6 +48,7 @@ #include #include #include +#include #include #include #include @@ -161,7 +162,8 @@ XclImpDrawObjBase::XclImpDrawObjBase( const XclImpRoot& rRoot ) : mbSimpleMacro( true ), mbProcessSdr( true ), mbInsertSdr( true ), - mbCustomDff( false ) + mbCustomDff( false ), + mbNotifyMacroEventRead( false ) { } @@ -497,7 +499,18 @@ SdrObjectPtr XclImpDrawObjBase::CreateSdrObject( XclImpDffConverter& rDffConv, c return xSdrObj; } -void XclImpDrawObjBase::PreProcessSdrObject( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const +void XclImpDrawObjBase::NotifyMacroEventRead() +{ + if (mbNotifyMacroEventRead) + return; + SfxObjectShell* pDocShell = GetDocShell(); + if (!pDocShell) + return; + comphelper::DocumentInfo::notifyMacroEventRead(pDocShell->GetModel()); + mbNotifyMacroEventRead = true; +} + +void XclImpDrawObjBase::PreProcessSdrObject( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) { // default: front layer, derived classes may have to set other layer in DoPreProcessSdrObj() rSdrObj.NbcSetLayer( SC_LAYER_FRONT ); @@ -524,7 +537,10 @@ void XclImpDrawObjBase::PreProcessSdrObject( XclImpDffConverter& rDffConv, SdrOb { if( ScMacroInfo* pInfo = ScDrawLayer::GetMacroInfo( &rSdrObj, true ) ) { - pInfo->SetMacro( XclTools::GetSbMacroUrl( maMacroName, GetDocShell() ) ); + OUString sMacro = XclTools::GetSbMacroUrl(maMacroName, GetDocShell()); + if (!sMacro.isEmpty()) + NotifyMacroEventRead(); + pInfo->SetMacro(sMacro); pInfo->SetHlink( maHyperlink ); } } @@ -3271,7 +3287,8 @@ XclImpDffConverter::XclImpDffConverter( const XclImpRoot& rRoot, SvStream& rDffS XclImpSimpleDffConverter( rRoot, rDffStrm ), oox::ole::MSConvertOCXControls( rRoot.GetDocShell()->GetModel() ), maStdFormName( "Standard" ), - mnOleImpFlags( 0 ) + mnOleImpFlags( 0 ), + mbNotifyMacroEventRead(false) { const SvtFilterOptions& rFilterOpt = SvtFilterOptions::Get(); if( rFilterOpt.IsMathType2Math() ) @@ -3328,7 +3345,7 @@ void XclImpDffConverter::InitializeDrawing( XclImpDrawing& rDrawing, SdrModel& r SetModel( &xConvData->mrSdrModel, 1440 ); } -void XclImpDffConverter::ProcessObject( SdrObjList& rObjList, const XclImpDrawObjBase& rDrawObj ) +void XclImpDffConverter::ProcessObject( SdrObjList& rObjList, XclImpDrawObjBase& rDrawObj ) { if( rDrawObj.IsProcessSdrObj() ) { @@ -3378,6 +3395,14 @@ void XclImpDffConverter::FinalizeDrawing() SetModel( &maDataStack.back()->mrSdrModel, 1440 ); } +void XclImpDffConverter::NotifyMacroEventRead() +{ + if (mbNotifyMacroEventRead) + return; + comphelper::DocumentInfo::notifyMacroEventRead(mxModel); + mbNotifyMacroEventRead = true; +} + SdrObjectPtr XclImpDffConverter::CreateSdrObject( const XclImpTbxObjBase& rTbxObj, const tools::Rectangle& rAnchorRect ) { SdrObjectPtr xSdrObj; @@ -3400,6 +3425,7 @@ SdrObjectPtr XclImpDffConverter::CreateSdrObject( const XclImpTbxObjBase& rTbxOb ScriptEventDescriptor aDescriptor; if( (rConvData.mnLastCtrlIndex >= 0) && rTbxObj.FillMacroDescriptor( aDescriptor ) ) { + NotifyMacroEventRead(); Reference< XEventAttacherManager > xEventMgr( rConvData.mxCtrlForm, UNO_QUERY_THROW ); xEventMgr->registerScriptEvent( rConvData.mnLastCtrlIndex, aDescriptor ); } diff --git a/sc/source/filter/inc/xiescher.hxx b/sc/source/filter/inc/xiescher.hxx index 015b7c74524..2d42ff6437f 100644 --- a/sc/source/filter/inc/xiescher.hxx +++ b/sc/source/filter/inc/xiescher.hxx @@ -126,7 +126,7 @@ public: SdrObjectPtr CreateSdrObject( XclImpDffConverter& rDffConv, const tools::Rectangle& rAnchorRect, bool bIsDff ) const; /** Additional processing for the passed SdrObject before insertion into the drawing page (calls virtual DoPreProcessSdrObj() function). */ - void PreProcessSdrObject( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const; + void PreProcessSdrObject( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ); /** Additional processing for the passed SdrObject after insertion into the drawing page (calls virtual DoPostProcessSdrObj() function). */ void PostProcessSdrObject( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const; @@ -173,6 +173,9 @@ protected: virtual void DoPreProcessSdrObj( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const; /** Derived classes may perform additional processing for the passed SdrObject after insertion. */ virtual void DoPostProcessSdrObj( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const; + + /** Notify that the document contains a macro event handler */ + void NotifyMacroEventRead(); private: /** Reads the contents of a BIFF3 OBJ record. */ void ImplReadObj3( XclImpStream& rStrm ); @@ -203,6 +206,7 @@ private: bool mbProcessSdr; /// true = Object is valid, do processing and insertion. bool mbInsertSdr; /// true = Insert the SdrObject into draw page. bool mbCustomDff; /// true = Recreate SdrObject in DFF import. + bool mbNotifyMacroEventRead; /// true == If we have already seen a macro event }; class XclImpDrawObjVector @@ -929,7 +933,7 @@ public: /** Initially called before the objects of the passed drawing manager are converted. */ void InitializeDrawing( XclImpDrawing& rDrawing, SdrModel& rSdrModel, SdrPage& rSdrPage ); /** Processes BIFF5 drawing objects without DFF data, inserts into the passed object list. */ - void ProcessObject( SdrObjList& rObjList, const XclImpDrawObjBase& rDrawObj ); + void ProcessObject( SdrObjList& rObjList, XclImpDrawObjBase& rDrawObj ); /** Processes all objects in the passed list. */ void ProcessDrawing( const XclImpDrawObjVector& rDrawObjs ); /** Processes a drawing container in the passed DFF stream, converts all objects. */ @@ -1018,6 +1022,8 @@ private: void InsertSdrObject( SdrObjList& rObjList, const XclImpDrawObjBase& rDrawObj, SdrObject* pSdrObj ); /** Initializes the mxCtrlForm referring to the standard controls form. */ void InitControlForm(); + /** Notify that this document contains a macro event handler */ + void NotifyMacroEventRead(); private: typedef std::shared_ptr< ScfProgressBar > ScfProgressBarRef; @@ -1030,6 +1036,7 @@ private: XclImpDffConvDataStack maDataStack; /// Stack for registered drawing managers. sal_uInt32 mnOleImpFlags; /// Application OLE import settings. sal_Int32 mnDefTextMargin; /// Default margin in text boxes. + bool mbNotifyMacroEventRead; /// If we have already seen a macro event }; // Drawing manager ============================================================ diff --git a/sc/source/ui/vba/vbasheetobject.cxx b/sc/source/ui/vba/vbasheetobject.cxx index ac58ce94032..6680952bce1 100644 --- a/sc/source/ui/vba/vbasheetobject.cxx +++ b/sc/source/ui/vba/vbasheetobject.cxx @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -296,7 +297,8 @@ ScVbaControlObjectBase::ScVbaControlObjectBase( ListenerType eListenerType ) : ScVbaControlObject_BASE( rxParent, rxContext, rxModel, uno::Reference< drawing::XShape >( rxControlShape, uno::UNO_QUERY_THROW ) ), mxFormIC( rxFormIC, uno::UNO_SET_THROW ), - mxControlProps( rxControlShape->getControl(), uno::UNO_QUERY_THROW ) + mxControlProps( rxControlShape->getControl(), uno::UNO_QUERY_THROW ), + mbNotifyMacroEventRead(false) { // set listener and event name to be used for OnAction attribute switch( eListenerType ) @@ -354,6 +356,14 @@ OUString SAL_CALL ScVbaControlObjectBase::getOnAction() return OUString(); } +void ScVbaControlObjectBase::NotifyMacroEventRead() +{ + if (mbNotifyMacroEventRead) + return; + comphelper::DocumentInfo::notifyMacroEventRead(mxModel); + mbNotifyMacroEventRead = true; +} + void SAL_CALL ScVbaControlObjectBase::setOnAction( const OUString& rMacroName ) { uno::Reference< script::XEventAttacherManager > xEventMgr( mxFormIC, uno::UNO_QUERY_THROW ); @@ -373,6 +383,7 @@ void SAL_CALL ScVbaControlObjectBase::setOnAction( const OUString& rMacroName ) aDescriptor.EventMethod = maEventMethod; aDescriptor.ScriptType = "Script"; aDescriptor.ScriptCode = makeMacroURL( aResolvedMacro.msResolvedMacro ); + NotifyMacroEventRead(); xEventMgr->registerScriptEvent( nIndex, aDescriptor ); } } diff --git a/sc/source/ui/vba/vbasheetobject.hxx b/sc/source/ui/vba/vbasheetobject.hxx index 721bcf99a24..9bc18954c0d 100644 --- a/sc/source/ui/vba/vbasheetobject.hxx +++ b/sc/source/ui/vba/vbasheetobject.hxx @@ -164,6 +164,9 @@ public: virtual sal_Bool SAL_CALL getAutoSize() override; virtual void SAL_CALL setAutoSize( sal_Bool bAutoSize ) override; + /// Notify that the document contains a macro event handler + void NotifyMacroEventRead(); + protected: /// @throws css::uno::RuntimeException sal_Int32 getModelIndexInForm() const; @@ -173,6 +176,7 @@ protected: css::uno::Reference< css::beans::XPropertySet > mxControlProps; OUString maListenerType; OUString maEventMethod; + bool mbNotifyMacroEventRead; }; typedef ::cppu::ImplInheritanceHelper< ScVbaControlObjectBase, ov::excel::XButton > ScVbaButton_BASE; diff --git a/scripting/source/protocolhandler/scripthandler.cxx b/scripting/source/protocolhandler/scripthandler.cxx index e7cd12a21f0..85b9f3eccb3 100644 --- a/scripting/source/protocolhandler/scripthandler.cxx +++ b/scripting/source/protocolhandler/scripthandler.cxx @@ -124,7 +124,6 @@ void SAL_CALL ScriptProtocolHandler::dispatchWithNotification( const URL& aURL, const Sequence < PropertyValue >& lArgs, const Reference< XDispatchResultListener >& xListener ) { - bool bSuccess = false; Any invokeResult; bool bCaughtException = false; @@ -161,12 +160,11 @@ void SAL_CALL ScriptProtocolHandler::dispatchWithNotification( { xListener->dispatchFinished( aEvent ) ; } - catch(RuntimeException & e) + catch(const RuntimeException &e) { SAL_WARN("scripting", "ScriptProtocolHandler::dispatchWithNotification: caught RuntimeException" - "while dispatchFinished with failure of the execution " - << e ); + "while dispatchFinished with failure of the execution" << e); } } return; diff --git a/sfx2/source/doc/docmacromode.cxx b/sfx2/source/doc/docmacromode.cxx index c62a5ab87d9..6e01b925d51 100644 --- a/sfx2/source/doc/docmacromode.cxx +++ b/sfx2/source/doc/docmacromode.cxx @@ -397,7 +397,7 @@ namespace sfx2 } else { - if ( m_xData->m_rDocumentAccess.documentStorageHasMacros() || hasMacroLibrary() ) + if (m_xData->m_rDocumentAccess.documentStorageHasMacros() || hasMacroLibrary() || m_xData->m_rDocumentAccess.macroCallsSeenWhileLoading()) { bAllow = adjustMacroMode( rxInteraction ); } diff --git a/sfx2/source/doc/objmisc.cxx b/sfx2/source/doc/objmisc.cxx index 0c9d1a8f7e4..248cabf92f6 100644 --- a/sfx2/source/doc/objmisc.cxx +++ b/sfx2/source/doc/objmisc.cxx @@ -1390,13 +1390,7 @@ ErrCode SfxObjectShell::CallXScript( const Reference< XInterface >& _rxScriptCon Any aException; try { - css::uno::Reference urifac( - css::uri::UriReferenceFactory::create(comphelper::getProcessComponentContext())); - css::uno::Reference uri( - urifac->parse(_rScriptURL), css::uno::UNO_QUERY_THROW); - auto const loc = uri->getParameter("location"); - bool bIsDocumentScript = loc == "document"; - if ( bIsDocumentScript && !lcl_isScriptAccessAllowed_nothrow( _rxScriptContext ) ) + if ( !lcl_isScriptAccessAllowed_nothrow( _rxScriptContext ) ) return ERRCODE_IO_ACCESSDENIED; if ( UnTrustedScript(_rScriptURL) ) @@ -1773,6 +1767,11 @@ bool SfxObjectShell_Impl::documentStorageHasMacros() const return ::sfx2::DocumentMacroMode::storageHasMacros( m_xDocStorage ); } +bool SfxObjectShell_Impl::macroCallsSeenWhileLoading() const +{ + return rDocShell.GetMacroCallsSeenWhileLoading(); +} + Reference< XEmbeddedScripts > SfxObjectShell_Impl::getEmbeddedDocumentScripts() const { return Reference< XEmbeddedScripts >( rDocShell.GetModel(), UNO_QUERY ); diff --git a/sfx2/source/doc/objstor.cxx b/sfx2/source/doc/objstor.cxx index 716455cda9a..0b4b933318a 100644 --- a/sfx2/source/doc/objstor.cxx +++ b/sfx2/source/doc/objstor.cxx @@ -3562,6 +3562,16 @@ void SfxObjectShell::SetConfigOptionsChecked( bool bChecked ) pImpl->m_bConfigOptionsChecked = bChecked; } +void SfxObjectShell::SetMacroCallsSeenWhileLoading() +{ + pImpl->m_bMacroCallsSeenWhileLoading = true; +} + +bool SfxObjectShell::GetMacroCallsSeenWhileLoading() const +{ + return pImpl->m_bMacroCallsSeenWhileLoading; +} + bool SfxObjectShell::QuerySaveSizeExceededModules_Impl( const uno::Reference< task::XInteractionHandler >& xHandler ) { #if !HAVE_FEATURE_SCRIPTING diff --git a/sfx2/source/doc/objxtor.cxx b/sfx2/source/doc/objxtor.cxx index 88270d13f4a..b3309bae2d8 100644 --- a/sfx2/source/doc/objxtor.cxx +++ b/sfx2/source/doc/objxtor.cxx @@ -230,6 +230,7 @@ SfxObjectShell_Impl::SfxObjectShell_Impl( SfxObjectShell& _rDocShell ) ,m_bSharedXMLFlag( false ) ,m_bAllowShareControlFileClean( true ) ,m_bConfigOptionsChecked( false ) + ,m_bMacroCallsSeenWhileLoading( false ) ,lErr(ERRCODE_NONE) ,nEventId ( SfxEventHintId::NONE ) ,pReloadTimer ( nullptr) diff --git a/sfx2/source/doc/sfxbasemodel.cxx b/sfx2/source/doc/sfxbasemodel.cxx index 752bec0ebc0..1bbba2372d6 100644 --- a/sfx2/source/doc/sfxbasemodel.cxx +++ b/sfx2/source/doc/sfxbasemodel.cxx @@ -875,8 +875,15 @@ sal_Bool SAL_CALL SfxBaseModel::attachResource( const OUString& pObjectShell->BreakMacroSign_Impl( bBreakMacroSign ); } + bool bMacroEventRead = false; + if ((aArgs.get("MacroEventRead") >>= bMacroEventRead) && bMacroEventRead) + { + pObjectShell->SetMacroCallsSeenWhileLoading(); + } + aArgs.remove( "WinExtent" ); aArgs.remove( "BreakMacroSignature" ); + aArgs.remove( "MacroEventRead" ); aArgs.remove( "Stream" ); aArgs.remove( "InputStream" ); aArgs.remove( "URL" ); diff --git a/sfx2/source/inc/objshimp.hxx b/sfx2/source/inc/objshimp.hxx index 67628d5dbdb..0b403e071d5 100644 --- a/sfx2/source/inc/objshimp.hxx +++ b/sfx2/source/inc/objshimp.hxx @@ -90,7 +90,8 @@ struct SfxObjectShell_Impl : public ::sfx2::IMacroDocumentAccess bSaveVersionOnClose:1, m_bSharedXMLFlag:1, // whether the document should be edited in shared mode m_bAllowShareControlFileClean:1, // whether the flag should be stored in xml file - m_bConfigOptionsChecked:1; // whether or not the user options are checked after the Options dialog is closed. + m_bConfigOptionsChecked:1, // whether or not the user options are checked after the Options dialog is closed. + m_bMacroCallsSeenWhileLoading:1; // whether or not the user options are checked after the Options dialog is closed. IndexBitSet aBitSet; ErrCode lErr; @@ -139,6 +140,7 @@ struct SfxObjectShell_Impl : public ::sfx2::IMacroDocumentAccess virtual void setCurrentMacroExecMode( sal_uInt16 nMacroMode ) override; virtual OUString getDocumentLocation() const override; virtual bool documentStorageHasMacros() const override; + virtual bool macroCallsSeenWhileLoading() const override; virtual css::uno::Reference< css::document::XEmbeddedScripts > getEmbeddedDocumentScripts() const override; virtual SignatureState getScriptingSignatureState() override; diff --git a/sfx2/source/notify/eventsupplier.cxx b/sfx2/source/notify/eventsupplier.cxx index 2656e9c213e..3861149da73 100644 --- a/sfx2/source/notify/eventsupplier.cxx +++ b/sfx2/source/notify/eventsupplier.cxx @@ -19,11 +19,13 @@ #include +#include +#include #include - #include #include #include +#include #include #include #include @@ -46,6 +48,8 @@ #include using namespace css; +using namespace ::com::sun::star; + // --- XNameReplace --- @@ -167,102 +171,129 @@ sal_Bool SAL_CALL SfxEvents_Impl::hasElements() return false; } +namespace +{ + bool lcl_isScriptAccessAllowed_nothrow(const uno::Reference& rxScriptContext) + { + try + { + uno::Reference xScripts(rxScriptContext, uno::UNO_QUERY); + if (!xScripts.is()) + { + uno::Reference xContext(rxScriptContext, uno::UNO_QUERY_THROW); + xScripts.set(xContext->getScriptContainer(), uno::UNO_SET_THROW); + } + + return xScripts->getAllowMacroExecution(); + } + catch( const uno::Exception& ) + { + DBG_UNHANDLED_EXCEPTION("sfx.doc"); + } + return false; + } +} + void SfxEvents_Impl::Execute( uno::Any const & aEventData, const document::DocumentEvent& aTrigger, SfxObjectShell* pDoc ) { uno::Sequence < beans::PropertyValue > aProperties; - if ( aEventData >>= aProperties ) - { - OUString aType; - OUString aScript; - OUString aLibrary; - OUString aMacroName; + if ( !(aEventData >>= aProperties) ) + return; - sal_Int32 nCount = aProperties.getLength(); + OUString aType; + OUString aScript; + OUString aLibrary; + OUString aMacroName; - if ( !nCount ) - return; + sal_Int32 nCount = aProperties.getLength(); - sal_Int32 nIndex = 0; - while ( nIndex < nCount ) - { - if ( aProperties[ nIndex ].Name == PROP_EVENT_TYPE ) - aProperties[ nIndex ].Value >>= aType; - else if ( aProperties[ nIndex ].Name == PROP_SCRIPT ) - aProperties[ nIndex ].Value >>= aScript; - else if ( aProperties[ nIndex ].Name == PROP_LIBRARY ) - aProperties[ nIndex ].Value >>= aLibrary; - else if ( aProperties[ nIndex ].Name == PROP_MACRO_NAME ) - aProperties[ nIndex ].Value >>= aMacroName; - else { - OSL_FAIL("Unknown property value!"); - } - nIndex += 1; - } + if ( !nCount ) + return; - if (aType == STAR_BASIC && !aScript.isEmpty()) - { - uno::Any aAny; - SfxMacroLoader::loadMacro( aScript, aAny, pDoc ); + sal_Int32 nIndex = 0; + while ( nIndex < nCount ) + { + if ( aProperties[ nIndex ].Name == PROP_EVENT_TYPE ) + aProperties[ nIndex ].Value >>= aType; + else if ( aProperties[ nIndex ].Name == PROP_SCRIPT ) + aProperties[ nIndex ].Value >>= aScript; + else if ( aProperties[ nIndex ].Name == PROP_LIBRARY ) + aProperties[ nIndex ].Value >>= aLibrary; + else if ( aProperties[ nIndex ].Name == PROP_MACRO_NAME ) + aProperties[ nIndex ].Value >>= aMacroName; + else { + OSL_FAIL("Unknown property value!"); } - else if (aType == "Service" || - aType == "Script") - { - bool bAllowed = false; - util::URL aURL; - if (!aScript.isEmpty()) - { - uno::Reference < util::XURLTransformer > xTrans( util::URLTransformer::create( ::comphelper::getProcessComponentContext() ) ); + nIndex += 1; + } - aURL.Complete = aScript; - xTrans->parseStrict( aURL ); + if (aType.isEmpty()) + { + // Empty type means no active binding for the event. Just ignore do nothing. + return; + } - bAllowed = !SfxObjectShell::UnTrustedScript(aURL.Complete); - } + if (aScript.isEmpty()) + return; - if (bAllowed) - { - SfxViewFrame* pView = pDoc ? - SfxViewFrame::GetFirst( pDoc ) : - SfxViewFrame::Current(); + if (!pDoc) + pDoc = SfxObjectShell::Current(); - uno::Reference - < frame::XDispatchProvider > xProv; + if (pDoc && !lcl_isScriptAccessAllowed_nothrow(pDoc->GetModel())) + return; - if ( pView != nullptr ) - { - xProv = uno::Reference - < frame::XDispatchProvider > ( - pView->GetFrame().GetFrameInterface(), uno::UNO_QUERY ); - } - else - { - xProv.set( frame::Desktop::create( ::comphelper::getProcessComponentContext() ), - uno::UNO_QUERY ); - } + if (aType == STAR_BASIC) + { + uno::Any aAny; + SfxMacroLoader::loadMacro( aScript, aAny, pDoc ); + } + else if (aType == "Service" || aType == "Script") + { + util::URL aURL; + uno::Reference < util::XURLTransformer > xTrans( util::URLTransformer::create( ::comphelper::getProcessComponentContext() ) ); - uno::Reference < frame::XDispatch > xDisp; - if ( xProv.is() ) - xDisp = xProv->queryDispatch( aURL, OUString(), 0 ); + aURL.Complete = aScript; + xTrans->parseStrict( aURL ); - if ( xDisp.is() ) - { + bool bAllowed = !SfxObjectShell::UnTrustedScript(aURL.Complete); - beans::PropertyValue aEventParam; - aEventParam.Value <<= aTrigger; - uno::Sequence< beans::PropertyValue > aDispatchArgs( &aEventParam, 1 ); - xDisp->dispatch( aURL, aDispatchArgs ); - } - } - } - else if ( aType.isEmpty() ) - { - // Empty type means no active binding for the event. Just ignore do nothing. - } - else + if (bAllowed) { - SAL_WARN( "sfx.notify", "notifyEvent(): Unsupported event type" ); + SfxViewFrame* pView = SfxViewFrame::GetFirst(pDoc); + + uno::Reference + < frame::XDispatchProvider > xProv; + + if ( pView != nullptr ) + { + xProv = uno::Reference + < frame::XDispatchProvider > ( + pView->GetFrame().GetFrameInterface(), uno::UNO_QUERY ); + } + else + { + xProv.set( frame::Desktop::create( ::comphelper::getProcessComponentContext() ), + uno::UNO_QUERY ); + } + + uno::Reference < frame::XDispatch > xDisp; + if ( xProv.is() ) + xDisp = xProv->queryDispatch( aURL, OUString(), 0 ); + + if ( xDisp.is() ) + { + + beans::PropertyValue aEventParam; + aEventParam.Value <<= aTrigger; + uno::Sequence< beans::PropertyValue > aDispatchArgs( &aEventParam, 1 ); + xDisp->dispatch( aURL, aDispatchArgs ); + } } } + else + { + SAL_WARN( "sfx.notify", "notifyEvent(): Unsupported event type" ); + } } diff --git a/sw/source/filter/html/htmlform.cxx b/sw/source/filter/html/htmlform.cxx index 358cac7388a..e6d06317809 100644 --- a/sw/source/filter/html/htmlform.cxx +++ b/sw/source/filter/html/htmlform.cxx @@ -18,6 +18,7 @@ */ #include +#include #include #include #include @@ -735,7 +736,7 @@ void SwHTMLParser::SetControlSize( const uno::Reference< drawing::XShape >& rSha rShape->setSize( aSz ); } -static void lcl_html_setEvents( +static bool lcl_html_setEvents( const uno::Reference< script::XEventAttacherManager > & rEvtMn, sal_uInt32 nPos, const SvxMacroTableDtor& rMacroTable, const std::vector& rUnoMacroTable, @@ -764,7 +765,7 @@ static void lcl_html_setEvents( } if( 0==nEvents ) - return; + return false; Sequence aDescs( nEvents ); script::ScriptEventDescriptor* pDescs = aDescs.getArray(); @@ -822,6 +823,7 @@ static void lcl_html_setEvents( } } rEvtMn->registerScriptEvents( nPos, aDescs ); + return true; } static void lcl_html_getEvents( const OUString& rOption, const OUString& rValue, @@ -1190,10 +1192,12 @@ uno::Reference< drawing::XShape > SwHTMLParser::InsertControl( // To prevent previous JavaScript-Events from being called, these events will only be set retroactively if( !rMacroTable.empty() || !rUnoMacroTable.empty() ) { - lcl_html_setEvents( m_pFormImpl->GetControlEventManager(), + bool bHasEvents = lcl_html_setEvents( m_pFormImpl->GetControlEventManager(), rFormComps->getCount() - 1, rMacroTable, rUnoMacroTable, rUnoMacroParamTable, GetScriptTypeString(m_pFormImpl->GetHeaderAttrs()) ); + if (bHasEvents) + NotifyMacroEventRead(); } if( bSetFCompPropSet ) @@ -1355,10 +1359,14 @@ void SwHTMLParser::NewForm( bool bAppend ) Any aAny( &xForm, cppu::UnoType::get()); rForms->insertByIndex( rForms->getCount(), aAny ); if( !aMacroTable.empty() ) - lcl_html_setEvents( m_pFormImpl->GetFormEventManager(), + { + bool bHasEvents = lcl_html_setEvents( m_pFormImpl->GetFormEventManager(), rForms->getCount() - 1, aMacroTable, aUnoMacroTable, aUnoMacroParamTable, rDfltScriptType ); + if (bHasEvents) + NotifyMacroEventRead(); + } } void SwHTMLParser::EndForm( bool bAppend ) diff --git a/sw/source/filter/html/htmlgrin.cxx b/sw/source/filter/html/htmlgrin.cxx index 8e61296d538..9f6f93218b2 100644 --- a/sw/source/filter/html/htmlgrin.cxx +++ b/sw/source/filter/html/htmlgrin.cxx @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -866,7 +867,10 @@ IMAGE_SETEVENT: } if( !aMacroItem.GetMacroTable().empty() ) + { + NotifyMacroEventRead(); pFlyFormat->SetFormatAttr( aMacroItem ); + } // tdf#87083 If the graphic has not been loaded yet, then load it now. // Otherwise it may be loaded during the first paint of the object and it @@ -1297,7 +1301,10 @@ ANCHOR_SETEVENT: aINetFormat.SetName( aName ); if( !aMacroTable.empty() ) + { + NotifyMacroEventRead(); aINetFormat.SetMacroTable( &aMacroTable ); + } // set the default attribute InsertAttr(&m_xAttrTab->pINetFormat, aINetFormat, xCntxt.get()); @@ -1509,4 +1516,16 @@ void SwHTMLParser::StripTrailingPara() } } +void SwHTMLParser::NotifyMacroEventRead() +{ + if (m_bNotifyMacroEventRead) + return; + SwDocShell *pDocSh = m_xDoc->GetDocShell(); + if (!pDocSh) + return; + uno::Reference const xModel(pDocSh->GetBaseModel()); + comphelper::DocumentInfo::notifyMacroEventRead(xModel); + m_bNotifyMacroEventRead = true; +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/filter/html/swhtml.cxx b/sw/source/filter/html/swhtml.cxx index 508bbc1a467..85aa9eb5435 100644 --- a/sw/source/filter/html/swhtml.cxx +++ b/sw/source/filter/html/swhtml.cxx @@ -309,6 +309,7 @@ SwHTMLParser::SwHTMLParser( SwDoc* pD, SwPaM& rCursor, SvStream& rIn, m_bRemoveHidden( false ), m_bBodySeen( false ), m_bReadingHeaderOrFooter( false ), + m_bNotifyMacroEventRead( false ), m_isInTableStructure(false), m_nTableDepth( 0 ), m_pTempViewFrame(nullptr) diff --git a/sw/source/filter/html/swhtml.hxx b/sw/source/filter/html/swhtml.hxx index d649f4a123e..34a7260f85e 100644 --- a/sw/source/filter/html/swhtml.hxx +++ b/sw/source/filter/html/swhtml.hxx @@ -496,6 +496,7 @@ class SwHTMLParser : public SfxHTMLParser, public SwClient bool m_bBodySeen : 1; bool m_bReadingHeaderOrFooter : 1; + bool m_bNotifyMacroEventRead : 1; bool m_isInTableStructure; sal_Int32 m_nTableDepth; @@ -963,6 +964,9 @@ public: } void DeregisterHTMLTable(HTMLTable* pOld); + + void NotifyMacroEventRead(); + }; struct SwPendingStackData diff --git a/sw/source/filter/ww8/ww8par.cxx b/sw/source/filter/ww8/ww8par.cxx index bcc16adc2d9..f63916d6f49 100644 Binary files a/sw/source/filter/ww8/ww8par.cxx and b/sw/source/filter/ww8/ww8par.cxx differ diff --git a/sw/source/filter/ww8/ww8par.hxx b/sw/source/filter/ww8/ww8par.hxx index b4fbecfef44..1a1f988e32e 100644 --- a/sw/source/filter/ww8/ww8par.hxx +++ b/sw/source/filter/ww8/ww8par.hxx @@ -1367,6 +1367,7 @@ private: cp_vector m_aEndParaPos; WW8_CP m_aCurrAttrCP; bool m_bOnLoadingMain:1; + bool m_bNotifyMacroEventRead:1; const SprmReadInfo& GetSprmReadInfo(sal_uInt16 nId) const; @@ -1897,6 +1898,7 @@ public: // really private, but can only be done public void PostProcessAttrs(); void ReadEmbeddedData(SvStream& rStrm, SwDocShell const * pDocShell, struct HyperLinksTable& hlStr); + void NotifyMacroEventRead(); }; bool CanUseRemoteLink(const OUString &rGrfName); diff --git a/sw/source/filter/ww8/ww8par5.cxx b/sw/source/filter/ww8/ww8par5.cxx index 4d1f84a9ad7..e592073b399 100644 --- a/sw/source/filter/ww8/ww8par5.cxx +++ b/sw/source/filter/ww8/ww8par5.cxx @@ -2274,6 +2274,8 @@ eF_ResT SwWW8ImplReader::Read_F_Macro( WW8FieldDesc*, OUString& rStr) if( aName.isEmpty() ) return eF_ResT::TAGIGN; // makes no sense without Macro-Name + NotifyMacroEventRead(); + //try converting macro symbol according to macro name bool bApplyWingdings = ConvertMacroSymbol( aName, aVText ); aName = "StarOffice.Standard.Modul1." + aName; diff --git a/sw/source/filter/ww8/ww8toolbar.cxx b/sw/source/filter/ww8/ww8toolbar.cxx index b7dc69dc92b..2a4242cdef5 100644 --- a/sw/source/filter/ww8/ww8toolbar.cxx +++ b/sw/source/filter/ww8/ww8toolbar.cxx @@ -18,8 +18,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -718,6 +720,10 @@ bool Tcg255::ImportCustomToolBar( SfxObjectShell& rDocSh ) SwCTBWrapper* pCTBWrapper = dynamic_cast< SwCTBWrapper* > ( *it ); if ( pCTBWrapper ) { + // tdf#127048 set this flag if we might import something + uno::Reference const xModel(rDocSh.GetBaseModel()); + comphelper::DocumentInfo::notifyMacroEventRead(xModel); + if ( !pCTBWrapper->ImportCustomToolBar( rDocSh ) ) return false; } diff --git a/xmloff/source/core/xmlimp.cxx b/xmloff/source/core/xmlimp.cxx index fdf943d775a..cf55462b460 100644 --- a/xmloff/source/core/xmlimp.cxx +++ b/xmloff/source/core/xmlimp.cxx @@ -57,6 +57,7 @@ #include #include #include +#include #include #include #include @@ -399,7 +400,8 @@ SvXMLImport::SvXMLImport( maNamespaceHandler( new SvXMLImportFastNamespaceHandler() ), mxFastDocumentHandler( nullptr ), mbIsFormsSupported( true ), - mbIsTableShapeSupported( false ) + mbIsTableShapeSupported( false ), + mbNotifyMacroEventRead( false ) { SAL_WARN_IF( !xContext.is(), "xmloff.core", "got no service manager" ); InitCtor_(); @@ -2177,6 +2179,16 @@ void SvXMLImport::registerNamespaces() } } +void SvXMLImport::NotifyMacroEventRead() +{ + if (mbNotifyMacroEventRead) + return; + + comphelper::DocumentInfo::notifyMacroEventRead(mxModel); + + mbNotifyMacroEventRead = true; +} + SvXMLImportFastNamespaceHandler::SvXMLImportFastNamespaceHandler() { } diff --git a/xmloff/source/script/XMLEventImportHelper.cxx b/xmloff/source/script/XMLEventImportHelper.cxx index 0e45525856a..93fd43da93e 100644 --- a/xmloff/source/script/XMLEventImportHelper.cxx +++ b/xmloff/source/script/XMLEventImportHelper.cxx @@ -36,7 +36,6 @@ XMLEventImportHelper::XMLEventImportHelper() : { } - XMLEventImportHelper::~XMLEventImportHelper() { // delete factories @@ -117,6 +116,8 @@ SvXMLImportContext* XMLEventImportHelper::CreateContext( const OUString& rXmlEventName, const OUString& rLanguage) { + rImport.NotifyMacroEventRead(); + SvXMLImportContext* pContext = nullptr; // translate event name form xml to api