crashtesting: hold the same document BasicManager only once

crash on converting forums/ods/forum-en-39357.ods to xls, and on
recalculating INDIRECT cells in 14 other documents, a debug build
asserts:

 soffice.bin: svl/source/notify/lstner.cxx:83: void SfxListener::StartListening(SfxBroadcaster&, DuplicateHandling): Assertion `!(bListeningAlready && eDuplicateHanding == DuplicateHandling::Unexpected) && "duplicate listener, try building with DBG_UTIL to find the other insert site."' failed.

 #21 SfxListener::StartListening(SfxBroadcaster&, DuplicateHandling) at svl/source/notify/lstner.cxx:83
 #22 SfxBasicManagerHolder::reset(BasicManager*) at sfx2/source/appl/appbaslib.cxx:70
 #23 SfxObjectShell::InitBasicManager_Impl() at sfx2/source/doc/objxtor.cxx:845
 #24 lcl_getBasicManagerForDocument(SfxObjectShell const&) at sfx2/source/doc/objxtor.cxx:656
 #25 SfxObjectShell::GetBasicManager() const at sfx2/source/doc/objxtor.cxx:690
 #26 SfxObjectShell::GetBasic() const at sfx2/source/doc/objxtor.cxx:799
 #27 ScCompiler::ParseMacro(rtl::OUString const&, bool) at sc/source/core/tool/compiler.cxx:3830
 #28 ScCompiler::NextNewToken(bool) at sc/source/core/tool/compiler.cxx:5137
 #29 ScCompiler::CompileString(rtl::OUString const&) at sc/source/core/tool/compiler.cxx:5293
 #30 XclExpChSourceLink::ConvertDataSequence(...) at sc/source/filter/excel/xechart.cxx:901

and the first StartListening of the pair was:

 SfxBasicManagerHolder::reset(BasicManager*) at sfx2/source/appl/appbaslib.cxx:71
 SfxObjectShell::InitBasicManager_Impl() at sfx2/source/doc/objxtor.cxx:845
 lcl_getBasicManagerForDocument(SfxObjectShell const&) at sfx2/source/doc/objxtor.cxx:657
 SfxObjectShell::GetBasicManager() const at sfx2/source/doc/objxtor.cxx:690
 ScServiceProvider::MakeInstance(ScServiceProvider::Type, ScDocShell*) at sc/source/ui/unoobj/servuno.cxx:590
 ScModelObj::createInstance(rtl::OUString const&) at sc/source/ui/unoobj/docuno.cxx:4085
 basic::SfxScriptLibraryContainer::importLibraryElement(...)

Creating the BasicManager of a VBA mode document loads its VBA
document modules, and they create the VBA globals, which asks for
the document's BasicManager again. That nested InitBasicManager_Impl
gets the BasicManager under construction from the repository and
passes it to the holder, then the outer one passes the same one
again, so the holder starts listening to it twice.

That recursion is old, but crashtesting only reaches it since:

commit c8da2d3a99b3a318545f1947f57c929ac9b9a82d
Date:   Sat Sep 26 20:23:11 2026 +0000

    load the Basic project of a VBA mode Calc document after import
    Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/13614

Previously the import loaded the Basic project at once and the first
request for the BasicManager came from inside that load. Now with
macros not allowed the project stays unloaded, so the first request
comes later, from a formula, and the load runs inside it.

so make SfxBasicManagerHolder::reset do nothing when it is given the
BasicManager it already holds

Signed-off-by: Caolán McNamara <caolan.mcnamara@collabora.com>
Change-Id: I5db2184ae0124879e47310d90b5371e1e2fb0235
Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/14516
Reviewed-by: Noel Grandin <noel.grandin@collabora.com>
Tested-by: Jenkins CPCI <releng@collaboraoffice.com>
(cherry picked from commit a095496e0d649882531fd8e211ec4179333adee0)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/211941
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
Tested-by: Jenkins
This commit is contained in:
Caolán McNamara
2026-10-07 12:46:22 +02:00
committed by Xisco Fauli
parent e1b35f0bb1
commit b1df3b5b7a
3 changed files with 25 additions and 0 deletions
Binary file not shown.
+20
View File
@@ -7,6 +7,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#include <com/sun/star/document/MacroExecMode.hpp>
#include <com/sun/star/document/UpdateDocMode.hpp>
#include <drwlayer.hxx>
#include <comphelper/propertyvalue.hxx>
@@ -160,6 +161,25 @@ CPPUNIT_TEST_FIXTURE(ScFiltersTest, testDrawImageRemoteNotFetched)
CPPUNIT_ASSERT(pDoc);
}
CPPUNIT_TEST_FIXTURE(ScFiltersTest, testVBADocumentBasicAfterLoad)
{
// A document in VBA compatibility mode with a VBA document module, loaded with macros not
// allowed, gets its Basic only when something first asks for it. Here that is the INDIRECT
// in A1 compiling "FOO" during a recalculation. Loading the document module asks for the
// document Basic again while the first request is still creating it.
uno::Sequence<beans::PropertyValue> aParams = {
comphelper::makePropertyValue(u"MacroExecutionMode"_ustr,
css::document::MacroExecMode::NEVER_EXECUTE),
};
loadFromFile(u"ods/vba-document-module.ods", aParams);
ScDocShell* pDocSh = getScDocShell();
pDocSh->DoHardRecalc();
CPPUNIT_ASSERT_EQUAL(u"#REF!"_ustr, getScDoc()->GetString(ScAddress(0, 0, 0)));
CPPUNIT_ASSERT(pDocSh->GetBasic());
}
CPPUNIT_TEST_FIXTURE(ScFiltersTest, testContentODS)
{
createScDoc("ods/universal-content.ods");
+5
View File
@@ -51,6 +51,11 @@ void SfxBasicManagerHolder::Notify(SfxBroadcaster& rBC, SfxHint const& rHint)
void SfxBasicManagerHolder::reset( BasicManager* _pBasicManager )
{
// A document's Basic manager can be handed over a second time while it is still being
// created. The holder already listens to it and holds its containers, so it stays as it is.
if ( _pBasicManager == mpBasicManager )
return;
impl_releaseContainers();
#if !HAVE_FEATURE_SCRIPTING