lsan:fix leak of VbaEventsHelperBase instances

triggers when running
   make CppunitTest_sc_macros_test CPPUNIT_TEST_NAME=testMacroButtonFormControlXlsxExport
under an ASAN build with detect_leaks=1

VbaEventsHelperBase registers listeners, which creates a ref-count cycle,
so it needs to implement the XComponent dispose() mechanism.

While we are at it, fix the same issue in SwDoc

Change-Id: Id1e24addf9788615d77a0976f6fe050d27421bb2

(cherry-pick manually from commit I9bfb72bc1c3df42229240f828add138aace3fa4c)
Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/1930
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
Tested-by: Jenkins CPCI <releng@collaboraoffice.com>

Change-Id: I764316c5718d3b9b78bc2f54d1024249964f5724
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/205021
Reviewed-by: Julien Nabet <serval2412@yahoo.fr>
Tested-by: Jenkins
This commit is contained in:
Noel Grandin
2026-05-10 13:54:35 +02:00
committed by Julien Nabet
parent 1621777daa
commit 25c08179be
5 changed files with 32 additions and 12 deletions
+8 -4
View File
@@ -32,7 +32,8 @@
#include <com/sun/star/uno/Reference.hxx>
#include <com/sun/star/uno/Sequence.hxx>
#include <com/sun/star/util/XChangesListener.hpp>
#include <cppuhelper/implbase.hxx>
#include <cppuhelper/basemutex.hxx>
#include <cppuhelper/compbase.hxx>
#include <rtl/ustring.hxx>
#include <sal/types.h>
#include <vbahelper/vbadllapi.h>
@@ -44,13 +45,13 @@ namespace com::sun::star {
class SfxObjectShell;
typedef ::cppu::WeakImplHelper<
typedef ::cppu::WeakComponentImplHelper<
css::script::vba::XVBAEventProcessor,
css::document::XEventListener,
css::util::XChangesListener,
css::lang::XServiceInfo > VbaEventsHelperBase_BASE;
class VBAHELPER_DLLPUBLIC VbaEventsHelperBase : public VbaEventsHelperBase_BASE
class VBAHELPER_DLLPUBLIC VbaEventsHelperBase : public cppu::BaseMutex, public VbaEventsHelperBase_BASE
{
public:
VbaEventsHelperBase(
@@ -69,9 +70,13 @@ public:
// lang::XEventListener
virtual void SAL_CALL disposing( const css::lang::EventObject& rEvent ) override;
using WeakComponentImplHelperBase::disposing;
sal_Bool SAL_CALL supportsService(OUString const & ServiceName) override;
// ::cppu::OComponentHelper
virtual void SAL_CALL disposing() override;
// little helpers ---------------------------------------------------------
bool hasModule(const OUString& rModuleName);
@@ -217,7 +222,6 @@ private:
EventHandlerPathMap maEventPaths;
css::uno::Reference< css::script::vba::XVBAModuleInfo > mxModuleInfos;
OUString maLibraryName;
bool mbDisposed;
};
+2
View File
@@ -85,6 +85,8 @@ void VBAMacroTest::testMacro(std::u16string_view aFileName, const OUString& rScr
if (!sFileUrl.isEmpty())
osl::File::remove(sFileUrl);
}
Scheduler::ProcessEventsToIdle();
}
CPPUNIT_TEST_FIXTURE(VBAMacroTest, testSimpleCopyAndPaste)
+4
View File
@@ -39,6 +39,8 @@
#include <sal/log.hxx>
#include <osl/diagnose.h>
#include <comphelper/configuration.hxx>
#include <comphelper/types.hxx>
#include <com/sun/star/script/vba/XVBAEventProcessor.hpp>
#include <scmod.hxx>
#include <scresid.hxx>
@@ -413,6 +415,8 @@ ScDocument::~ScDocument()
Clear( true ); // true = from destructor (needed for SdrModel::ClearModel)
::comphelper::disposeComponent(mxVbaEvents);
pValidationList.reset();
pRangeName.reset();
pDBCollection.reset();
+4
View File
@@ -29,6 +29,7 @@
#include <doc.hxx>
#include <proofreadingiterator.hxx>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/script/vba/XVBAEventProcessor.hpp>
#include <com/sun/star/text/XFlatParagraphIteratorProvider.hpp>
#include <com/sun/star/linguistic2/XProofreadingIterator.hpp>
#include <com/sun/star/i18n/ScriptType.hpp>
@@ -36,6 +37,7 @@
#include <comphelper/configuration.hxx>
#include <comphelper/processfactory.hxx>
#include <comphelper/random.hxx>
#include <comphelper/types.hxx>
#include <sfx2/viewfrm.hxx>
#include <sfx2/XmlIdRegistry.hxx>
#include <sal/log.hxx>
@@ -425,6 +427,8 @@ SwDoc::~SwDoc()
mpURLStateChgd.reset();
::comphelper::disposeComponent(mxVbaEvents);
// Deactivate Undo notification from Draw
if( GetDocumentDrawModelManager().GetDrawModel() )
{
@@ -38,8 +38,8 @@ using namespace ::ooo::vba;
VbaEventsHelperBase::VbaEventsHelperBase( const uno::Sequence< uno::Any >& rArgs ) :
mpShell( nullptr ),
mbDisposed( true )
VbaEventsHelperBase_BASE(m_aMutex),
mpShell( nullptr )
{
try
{
@@ -49,13 +49,11 @@ VbaEventsHelperBase::VbaEventsHelperBase( const uno::Sequence< uno::Any >& rArgs
catch( uno::Exception& )
{
}
mbDisposed = mpShell == nullptr;
startListening();
}
VbaEventsHelperBase::~VbaEventsHelperBase()
{
SAL_WARN_IF( !mbDisposed, "vbahelper", "VbaEventsHelperBase::~VbaEventsHelperBase - missing disposing notification" );
}
sal_Bool SAL_CALL VbaEventsHelperBase::processVbaEvent( sal_Int32 nEventId, const uno::Sequence< uno::Any >& rArgs )
@@ -83,7 +81,7 @@ sal_Bool SAL_CALL VbaEventsHelperBase::processVbaEvent( sal_Int32 nEventId, cons
/* Check that all class members are available, and that we are not
disposed (this may have happened at any time during execution of
the last event handler). */
if( mbDisposed || !mxModel.is() || !mpShell )
if( !mxModel.is() || !mpShell )
throw uno::RuntimeException();
// get info for next event
@@ -186,6 +184,15 @@ void SAL_CALL VbaEventsHelperBase::disposing( const lang::EventObject& rEvent )
stopListening();
}
void SAL_CALL VbaEventsHelperBase::disposing()
{
stopListening();
mxModel.clear();
maEventInfos.clear();
maEventPaths.clear();
mxModuleInfos.clear();
}
sal_Bool VbaEventsHelperBase::supportsService(OUString const & ServiceName)
{
return cppu::supportsService(this, ServiceName);
@@ -219,7 +226,7 @@ void VbaEventsHelperBase::registerEventHandler( sal_Int32 nEventId, sal_Int32 nM
void VbaEventsHelperBase::startListening()
{
if( mbDisposed )
if(!mpShell)
return;
uno::Reference< document::XEventBroadcaster > xEventBroadcaster( mxModel, uno::UNO_QUERY );
@@ -229,7 +236,7 @@ void VbaEventsHelperBase::startListening()
void VbaEventsHelperBase::stopListening()
{
if( mbDisposed )
if(!mpShell)
return;
uno::Reference< document::XEventBroadcaster > xEventBroadcaster( mxModel, uno::UNO_QUERY );
@@ -239,7 +246,6 @@ void VbaEventsHelperBase::stopListening()
mxModel.clear();
mpShell = nullptr;
maEventInfos.clear();
mbDisposed = true;
}
sal_Bool SAL_CALL VbaEventsHelperBase::hasVbaEventHandler( sal_Int32 nEventId, const uno::Sequence< uno::Any >& rArgs )