summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xframework/inc/helper/documentundoguard.hxx68
-rw-r--r--framework/prj/d.lst1
-rwxr-xr-xframework/source/helper/documentundoguard.cxx272
-rw-r--r--framework/source/helper/makefile.mk3
-rw-r--r--framework/util/makefile.mk3
-rw-r--r--scripting/source/protocolhandler/makefile.mk1
-rw-r--r--scripting/source/protocolhandler/scripthandler.cxx6
-rw-r--r--sfx2/source/appl/appuno.cxx62
-rw-r--r--sfx2/source/doc/objmisc.cxx5
9 files changed, 395 insertions, 26 deletions
diff --git a/framework/inc/helper/documentundoguard.hxx b/framework/inc/helper/documentundoguard.hxx
new file mode 100755
index 000000000000..d5856341e30e
--- /dev/null
+++ b/framework/inc/helper/documentundoguard.hxx
@@ -0,0 +1,68 @@
+/*************************************************************************
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef FRAMEWORK_DOCUMENTUNDOGUARD_HXX
+#define FRAMEWORK_DOCUMENTUNDOGUARD_HXX
+
+/** === begin UNO includes === **/
+#include <com/sun/star/uno/XInterface.hpp>
+/** === end UNO includes === **/
+
+#include <boost/scoped_ptr.hpp>
+
+//......................................................................................................................
+namespace framework
+{
+//......................................................................................................................
+
+ //==================================================================================================================
+ //= DocumentUndoGuard
+ //==================================================================================================================
+ struct DocumentUndoGuard_Data;
+ /** a helper class guarding the Undo manager of a document
+
+ This class guards, within a given scope, the Undo Manager of a document (or another component supporting
+ the XUndoManagerSupplier interface). When entering the scope (i.e. when the <code>DocumentUndoGuard</code>
+ instances is constructed), the current state of the undo contexts of the undo manager is examined.
+ Upon leaving the scope (i.e. when the <code>DocumentUndoGuard</code> is destructed), the guard will execute
+ as many calls to <member scope="com::sun::star::document">XUndoManager::leaveUndoContext</member> as are
+ necessary to restore the manager's initial state.
+ */
+ class DocumentUndoGuard
+ {
+ public:
+ DocumentUndoGuard( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& i_undoSupplierComponent );
+ ~DocumentUndoGuard();
+
+ private:
+ ::boost::scoped_ptr< DocumentUndoGuard_Data > m_pData;
+ };
+
+//......................................................................................................................
+} // namespace framework
+//......................................................................................................................
+
+#endif // FRAMEWORK_DOCUMENTUNDOGUARD_HXX
diff --git a/framework/prj/d.lst b/framework/prj/d.lst
index d3a3d6dd153c..d9d030d95b5e 100644
--- a/framework/prj/d.lst
+++ b/framework/prj/d.lst
@@ -43,6 +43,7 @@ mkdir: %_DEST%\xml%_EXT%\uiconfig\modules\StartModule\statusbar
..\inc\interaction\preventduplicateinteraction.hxx %_DEST%\inc%_EXT%\framework\preventduplicateinteraction.hxx
..\inc\helper\titlehelper.hxx %_DEST%\inc%_EXT%\framework\titlehelper.hxx
..\inc\classes\framelistanalyzer.hxx %_DEST%\inc%_EXT%\framework\framelistanalyzer.hxx
+..\inc\helper\documentundoguard.hxx %_DEST%\inc%_EXT%\framework\documentundoguard.hxx
..\uiconfig\startmodule\menubar\*.xml %_DEST%\xml%_EXT%\uiconfig\modules\StartModule\menubar\*.xml
..\uiconfig\startmodule\toolbar\*.xml %_DEST%\xml%_EXT%\uiconfig\modules\StartModule\toolbar\*.xml
diff --git a/framework/source/helper/documentundoguard.cxx b/framework/source/helper/documentundoguard.cxx
new file mode 100755
index 000000000000..03e2fae5f6a6
--- /dev/null
+++ b/framework/source/helper/documentundoguard.cxx
@@ -0,0 +1,272 @@
+/*************************************************************************
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "precompiled_framework.hxx"
+
+#include <helper/documentundoguard.hxx>
+
+/** === begin UNO includes === **/
+#include <com/sun/star/document/XUndoManagerSupplier.hpp>
+/** === end UNO includes === **/
+
+#include <cppuhelper/implbase1.hxx>
+#include <rtl/ref.hxx>
+#include <tools/diagnose_ex.h>
+
+//......................................................................................................................
+namespace framework
+{
+//......................................................................................................................
+
+ /** === begin UNO using === **/
+ using ::com::sun::star::uno::Reference;
+ using ::com::sun::star::uno::XInterface;
+ using ::com::sun::star::uno::UNO_QUERY;
+ using ::com::sun::star::uno::UNO_QUERY_THROW;
+ using ::com::sun::star::uno::UNO_SET_THROW;
+ using ::com::sun::star::uno::Exception;
+ using ::com::sun::star::uno::RuntimeException;
+ using ::com::sun::star::uno::Any;
+ using ::com::sun::star::uno::makeAny;
+ using ::com::sun::star::uno::Sequence;
+ using ::com::sun::star::uno::Type;
+ using ::com::sun::star::document::XUndoManagerSupplier;
+ using ::com::sun::star::document::XUndoManager;
+ using ::com::sun::star::document::XUndoManagerListener;
+ using ::com::sun::star::document::UndoManagerEvent;
+ using ::com::sun::star::lang::EventObject;
+ /** === end UNO using === **/
+
+ //==================================================================================================================
+ //= UndoManagerContextListener
+ //==================================================================================================================
+ typedef ::cppu::WeakImplHelper1 < XUndoManagerListener
+ > UndoManagerContextListener_Base;
+ class UndoManagerContextListener : public UndoManagerContextListener_Base
+ {
+ public:
+ UndoManagerContextListener( const Reference< XUndoManager >& i_undoManager )
+ :m_xUndoManager( i_undoManager, UNO_SET_THROW )
+ ,m_nRelativeContextDepth( 0 )
+ ,m_documentDisposed( false )
+ {
+ osl_incrementInterlockedCount( &m_refCount );
+ {
+ m_xUndoManager->addUndoManagerListener( this );
+ }
+ osl_decrementInterlockedCount( &m_refCount );
+ }
+
+ UndoManagerContextListener()
+ {
+ }
+
+ void finish()
+ {
+ OSL_ENSURE( m_nRelativeContextDepth >= 0, "UndoManagerContextListener: more contexts left than entered?" );
+
+ if ( m_documentDisposed )
+ return;
+
+ // work with a copy of m_nRelativeContextDepth, to be independent from possible bugs in the
+ // listener notifications (where it would be decremented with every leaveUndoContext)
+ sal_Int32 nDepth = m_nRelativeContextDepth;
+ while ( nDepth-- > 0 )
+ {
+ m_xUndoManager->leaveUndoContext();
+ }
+ m_xUndoManager->removeUndoManagerListener( this );
+ }
+
+ // XUndoManagerListener
+ virtual void SAL_CALL undoActionAdded( const UndoManagerEvent& i_event ) throw (RuntimeException);
+ virtual void SAL_CALL actionUndone( const UndoManagerEvent& i_event ) throw (RuntimeException);
+ virtual void SAL_CALL actionRedone( const UndoManagerEvent& i_event ) throw (RuntimeException);
+ virtual void SAL_CALL allActionsCleared( const EventObject& i_event ) throw (RuntimeException);
+ virtual void SAL_CALL redoActionsCleared( const EventObject& i_event ) throw (RuntimeException);
+ virtual void SAL_CALL resetAll( const EventObject& i_event ) throw (RuntimeException);
+ virtual void SAL_CALL enteredContext( const UndoManagerEvent& i_event ) throw (RuntimeException);
+ virtual void SAL_CALL enteredHiddenContext( const UndoManagerEvent& i_event ) throw (RuntimeException);
+ virtual void SAL_CALL leftContext( const UndoManagerEvent& i_event ) throw (RuntimeException);
+ virtual void SAL_CALL leftHiddenContext( const UndoManagerEvent& i_event ) throw (RuntimeException);
+ virtual void SAL_CALL cancelledContext( const UndoManagerEvent& i_event ) throw (RuntimeException);
+
+ // XEventListener
+ virtual void SAL_CALL disposing( const EventObject& i_event ) throw (RuntimeException);
+
+ private:
+ Reference< XUndoManager > const m_xUndoManager;
+ oslInterlockedCount m_nRelativeContextDepth;
+ bool m_documentDisposed;
+ };
+
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL UndoManagerContextListener::undoActionAdded( const UndoManagerEvent& i_event ) throw (RuntimeException)
+ {
+ (void)i_event;
+ // not interested in
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL UndoManagerContextListener::actionUndone( const UndoManagerEvent& i_event ) throw (RuntimeException)
+ {
+ (void)i_event;
+ // not interested in
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL UndoManagerContextListener::actionRedone( const UndoManagerEvent& i_event ) throw (RuntimeException)
+ {
+ (void)i_event;
+ // not interested in
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL UndoManagerContextListener::allActionsCleared( const EventObject& i_event ) throw (RuntimeException)
+ {
+ (void)i_event;
+ // not interested in
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL UndoManagerContextListener::redoActionsCleared( const EventObject& i_event ) throw (RuntimeException)
+ {
+ (void)i_event;
+ // not interested in
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL UndoManagerContextListener::resetAll( const EventObject& i_event ) throw (RuntimeException)
+ {
+ (void)i_event;
+ m_nRelativeContextDepth = 0;
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL UndoManagerContextListener::enteredContext( const UndoManagerEvent& i_event ) throw (RuntimeException)
+ {
+ (void)i_event;
+ osl_incrementInterlockedCount( &m_nRelativeContextDepth );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL UndoManagerContextListener::enteredHiddenContext( const UndoManagerEvent& i_event ) throw (RuntimeException)
+ {
+ (void)i_event;
+ osl_incrementInterlockedCount( &m_nRelativeContextDepth );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL UndoManagerContextListener::leftContext( const UndoManagerEvent& i_event ) throw (RuntimeException)
+ {
+ (void)i_event;
+ osl_decrementInterlockedCount( &m_nRelativeContextDepth );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL UndoManagerContextListener::leftHiddenContext( const UndoManagerEvent& i_event ) throw (RuntimeException)
+ {
+ (void)i_event;
+ osl_decrementInterlockedCount( &m_nRelativeContextDepth );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL UndoManagerContextListener::cancelledContext( const UndoManagerEvent& i_event ) throw (RuntimeException)
+ {
+ (void)i_event;
+ osl_decrementInterlockedCount( &m_nRelativeContextDepth );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL UndoManagerContextListener::disposing( const EventObject& i_event ) throw (RuntimeException)
+ {
+ (void)i_event;
+ m_documentDisposed = true;
+ }
+
+ //==================================================================================================================
+ //= DocumentUndoGuard_Data
+ //==================================================================================================================
+ struct DocumentUndoGuard_Data
+ {
+ Reference< XUndoManager > xUndoManager;
+ ::rtl::Reference< UndoManagerContextListener > pContextListener;
+ };
+
+ namespace
+ {
+ //--------------------------------------------------------------------------------------------------------------
+ void lcl_init( DocumentUndoGuard_Data& i_data, const Reference< XInterface >& i_undoSupplierComponent )
+ {
+ try
+ {
+ Reference< XUndoManagerSupplier > xUndoSupplier( i_undoSupplierComponent, UNO_QUERY );
+ if ( xUndoSupplier.is() )
+ i_data.xUndoManager.set( xUndoSupplier->getUndoManager(), UNO_SET_THROW );
+
+ if ( i_data.xUndoManager.is() )
+ i_data.pContextListener.set( new UndoManagerContextListener( i_data.xUndoManager ) );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+
+ //--------------------------------------------------------------------------------------------------------------
+ void lcl_restore( DocumentUndoGuard_Data& i_data )
+ {
+ try
+ {
+ if ( i_data.pContextListener.is() )
+ i_data.pContextListener->finish();
+ i_data.pContextListener.clear();
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+ }
+
+ //==================================================================================================================
+ //= DocumentUndoGuard
+ //==================================================================================================================
+ //------------------------------------------------------------------------------------------------------------------
+ DocumentUndoGuard::DocumentUndoGuard( const Reference< XInterface >& i_undoSupplierComponent )
+ :m_pData( new DocumentUndoGuard_Data )
+ {
+ lcl_init( *m_pData, i_undoSupplierComponent );
+ }
+
+ DocumentUndoGuard::~DocumentUndoGuard()
+ {
+ lcl_restore( *m_pData );
+ }
+
+//......................................................................................................................
+} // namespace framework
+//......................................................................................................................
diff --git a/framework/source/helper/makefile.mk b/framework/source/helper/makefile.mk
index ed54c381160c..158fba424c51 100644
--- a/framework/source/helper/makefile.mk
+++ b/framework/source/helper/makefile.mk
@@ -62,7 +62,8 @@ SLOFILES= $(SLO)$/ocomponentaccess.obj \
$(SLO)$/tagwindowasmodified.obj \
$(SLO)$/titlebarupdate.obj \
$(SLO)$/titlehelper.obj \
- $(SLO)$/mischelper.obj
+ $(SLO)$/mischelper.obj \
+ $(SLO)$/documentundoguard.obj \
# --- Targets ------------------------------------------------------
diff --git a/framework/util/makefile.mk b/framework/util/makefile.mk
index a3f14341d3f3..3df1e6493c9f 100644
--- a/framework/util/makefile.mk
+++ b/framework/util/makefile.mk
@@ -99,7 +99,8 @@ LIB2OBJFILES= \
$(SLO)$/menuextensionsupplier.obj \
$(SLO)$/preventduplicateinteraction.obj \
$(SLO)$/framelistanalyzer.obj \
- $(SLO)$/titlehelper.obj
+ $(SLO)$/titlehelper.obj \
+ $(SLO)$/documentundoguard.obj \
# --- import classes library ---------------------------------------------------
diff --git a/scripting/source/protocolhandler/makefile.mk b/scripting/source/protocolhandler/makefile.mk
index ec69c00b209d..5a2e92bbbac3 100644
--- a/scripting/source/protocolhandler/makefile.mk
+++ b/scripting/source/protocolhandler/makefile.mk
@@ -45,6 +45,7 @@ SHL1TARGET= $(TARGET)$(DLLPOSTFIX)
SHL1STDLIBS= \
$(SFXLIB) \
+ $(FWELIB) \
$(CPPULIB) \
$(CPPUHELPERLIB) \
$(VCLLIB) \
diff --git a/scripting/source/protocolhandler/scripthandler.cxx b/scripting/source/protocolhandler/scripthandler.cxx
index 4e81426d7d53..7c24b98e5a71 100644
--- a/scripting/source/protocolhandler/scripthandler.cxx
+++ b/scripting/source/protocolhandler/scripthandler.cxx
@@ -53,6 +53,7 @@
#include <cppuhelper/factory.hxx>
#include <cppuhelper/exc_hlp.hxx>
#include <util/util.hxx>
+#include <framework/documentundoguard.hxx>
#include "com/sun/star/uno/XComponentContext.hpp"
#include "com/sun/star/uri/XUriReference.hpp"
@@ -207,6 +208,11 @@ void SAL_CALL ScriptProtocolHandler::dispatchWithNotification(
}
}
+ // attempt to protect the document against the script tampering with its Undo Context
+ ::std::auto_ptr< ::framework::DocumentUndoGuard > pUndoGuard;
+ if ( bIsDocumentScript )
+ pUndoGuard.reset( new ::framework::DocumentUndoGuard( m_xScriptInvocation ) );
+
bSuccess = sal_False;
while ( !bSuccess )
{
diff --git a/sfx2/source/appl/appuno.cxx b/sfx2/source/appl/appuno.cxx
index 239b5bd58d9b..eebc5a930c03 100644
--- a/sfx2/source/appl/appuno.cxx
+++ b/sfx2/source/appl/appuno.cxx
@@ -96,6 +96,7 @@
#include <tools/cachestr.hxx>
#include <osl/mutex.hxx>
#include <comphelper/sequence.hxx>
+#include <framework/documentundoguard.hxx>
#include <rtl/ustrbuf.hxx>
using namespace ::com::sun::star;
@@ -1771,18 +1772,21 @@ ErrCode SfxMacroLoader::loadMacro( const ::rtl::OUString& rURL, com::sun::star::
if ( pBasMgr )
{
- if ( pSh && pDoc )
+ const bool bIsAppBasic = ( pBasMgr == pAppMgr );
+ const bool bIsDocBasic = ( pBasMgr != pAppMgr );
+
+ if ( pDoc )
{
- // security check for macros from document basic if an SFX context (pSh) is given
+ // security check for macros from document basic if an SFX doc is given
if ( !pDoc->AdjustMacroMode( String() ) )
// check forbids execution
return ERRCODE_IO_ACCESSDENIED;
}
- else if ( pSh && pSh->GetMedium() )
+ else if ( pDoc && pDoc->GetMedium() )
{
- pSh->AdjustMacroMode( String() );
- SFX_ITEMSET_ARG( pSh->GetMedium()->GetItemSet(), pUpdateDocItem, SfxUInt16Item, SID_UPDATEDOCMODE, sal_False);
- SFX_ITEMSET_ARG( pSh->GetMedium()->GetItemSet(), pMacroExecModeItem, SfxUInt16Item, SID_MACROEXECMODE, sal_False);
+ pDoc->AdjustMacroMode( String() );
+ SFX_ITEMSET_ARG( pDoc->GetMedium()->GetItemSet(), pUpdateDocItem, SfxUInt16Item, SID_UPDATEDOCMODE, sal_False);
+ SFX_ITEMSET_ARG( pDoc->GetMedium()->GetItemSet(), pMacroExecModeItem, SfxUInt16Item, SID_MACROEXECMODE, sal_False);
if ( pUpdateDocItem && pMacroExecModeItem
&& pUpdateDocItem->GetValue() == document::UpdateDocMode::NO_UPDATE
&& pMacroExecModeItem->GetValue() == document::MacroExecMode::NEVER_EXECUTE )
@@ -1802,34 +1806,46 @@ ErrCode SfxMacroLoader::loadMacro( const ::rtl::OUString& rURL, com::sun::star::
if ( pBasMgr->HasMacro( aQualifiedMethod ) )
{
Any aOldThisComponent;
- if ( pSh )
+ const bool bSetDocMacroMode = ( pDoc != NULL ) && bIsDocBasic;
+ const bool bSetGlobalThisComponent = ( pDoc != NULL ) && bIsAppBasic;
+ if ( bSetDocMacroMode )
{
- if ( pBasMgr != pAppMgr )
- // mark document: it executes an own macro, so it's in a modal mode
- pSh->SetMacroMode_Impl( TRUE );
- if ( pBasMgr == pAppMgr )
- {
- // document is executed via AppBASIC, adjust ThisComponent variable
- aOldThisComponent = pAppMgr->SetGlobalUNOConstant( "ThisComponent", makeAny( pSh->GetModel() ) );
- }
+ // mark document: it executes an own macro, so it's in a modal mode
+ pDoc->SetMacroMode_Impl( TRUE );
+ }
+
+ if ( bSetGlobalThisComponent )
+ {
+ // document is executed via AppBASIC, adjust ThisComponent variable
+ aOldThisComponent = pAppMgr->SetGlobalUNOConstant( "ThisComponent", makeAny( pDoc->GetModel() ) );
}
// just to let the shell be alive
- SfxObjectShellRef rSh = pSh;
+ SfxObjectShellRef xKeepDocAlive = pDoc;
- SbxVariableRef retValRef = new SbxVariable;
- nErr = pBasMgr->ExecuteMacro( aQualifiedMethod, aArgs, retValRef );
- if ( nErr == ERRCODE_NONE )
- rRetval = sbxToUnoValue( retValRef );
+ {
+ // attempt to protect the document against the script tampering with its Undo Context
+ ::std::auto_ptr< ::framework::DocumentUndoGuard > pUndoGuard;
+ if ( bIsDocBasic )
+ pUndoGuard.reset( new ::framework::DocumentUndoGuard( pDoc->GetModel() ) );
+
+ // execute the method
+ SbxVariableRef retValRef = new SbxVariable;
+ nErr = pBasMgr->ExecuteMacro( aQualifiedMethod, aArgs, retValRef );
+ if ( nErr == ERRCODE_NONE )
+ rRetval = sbxToUnoValue( retValRef );
+ }
- if ( ( pBasMgr == pAppMgr ) && pSh )
+ if ( bSetGlobalThisComponent )
{
pAppMgr->SetGlobalUNOConstant( "ThisComponent", aOldThisComponent );
}
- if ( pSh && pSh->GetModel().is() )
+ if ( bSetDocMacroMode )
+ {
// remove flag for modal mode
- pSh->SetMacroMode_Impl( FALSE );
+ pDoc->SetMacroMode_Impl( FALSE );
+ }
}
else
nErr = ERRCODE_BASIC_PROC_UNDEFINED;
diff --git a/sfx2/source/doc/objmisc.cxx b/sfx2/source/doc/objmisc.cxx
index 0c4d4b64b204..7278baf816ee 100644
--- a/sfx2/source/doc/objmisc.cxx
+++ b/sfx2/source/doc/objmisc.cxx
@@ -118,6 +118,7 @@ using namespace ::com::sun::star::container;
#include <rtl/bootstrap.hxx>
#include <vcl/svapp.hxx>
#include <framework/interaction.hxx>
+#include <framework/documentundoguard.hxx>
#include <comphelper/storagehelper.hxx>
#include <comphelper/documentconstants.hxx>
@@ -1721,9 +1722,11 @@ ErrCode SfxObjectShell::CallXScript( const Reference< XInterface >& _rxScriptCon
xScriptProvider.set( xScriptProviderFactory->createScriptProvider( makeAny( _rxScriptContext ) ), UNO_SET_THROW );
}
+ // ry to protect the invocation context's undo manager (if present), just in case the script tampers with it
+ ::framework::DocumentUndoGuard aUndoGuard( _rxScriptContext.get() );
+
// obtain the script, and execute it
Reference< provider::XScript > xScript( xScriptProvider->getScript( _rScriptURL ), UNO_QUERY_THROW );
-
aRet = xScript->invoke( aParams, aOutParamIndex, aOutParam );
}
catch ( const uno::Exception& )