From 6601fe8419bc9b99ebee82c5b75bdc9c0dbfd583 Mon Sep 17 00:00:00 2001 From: Mike Kaganski Date: Mon, 22 Jun 2026 21:27:40 +0500 Subject: [PATCH] cool#15956: keep insertion order in NameContainer's getElementNames This is required to keep content of Basic/script-lc.xml and each Basic//script-lb.xml byte-identical on round-trip, which is necessary for signatures to stay valid; this broke after commit ea2a97438643a440e192dbe30d03988da65c6b18 (Simplify NameContainer, 2024-12-01). Signed-off-by: Mike Kaganski Change-Id: Ib30b701dce8bbcb919c88f5b66f5134150ded575 Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/5025 Tested-by: Jenkins CPCI Reviewed-by: Miklos Vajna (cherry picked from commit bfe67bc782cf89e944324042c8e53c42f4b6421b) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/207164 Reviewed-by: Xisco Fauli Tested-by: Jenkins --- basic/source/inc/namecont.hxx | 4 ++ basic/source/uno/namecont.cxx | 25 ++++++++++- sc/qa/extras/macros-test.cxx | 41 +++++++++++++++++- .../qa/unit/signing/data/Cool15956.ods | Bin 0 -> 15782 bytes xmlsecurity/qa/unit/signing/signing.cxx | 36 +++++++++++++++ 5 files changed, 104 insertions(+), 2 deletions(-) create mode 100644 xmlsecurity/qa/unit/signing/data/Cool15956.ods diff --git a/basic/source/inc/namecont.hxx b/basic/source/inc/namecont.hxx index 48d8bb950263..fa88639e9f17 100644 --- a/basic/source/inc/namecont.hxx +++ b/basic/source/inc/namecont.hxx @@ -20,6 +20,7 @@ #pragma once #include +#include #include #include #include @@ -58,6 +59,9 @@ class NameContainer final cppu::OWeakObject& rOwner; std::unordered_map maMap; + // Enumeration must keep insertion order: it drives the on-disk order of the + // library index file and module streams, which macro signatures sign over. + std::vector maNamesOrder; css::uno::Type mType; css::uno::XInterface* mpxEventSource; diff --git a/basic/source/uno/namecont.cxx b/basic/source/uno/namecont.cxx index 33ac0dee21af..ad2123f67133 100644 --- a/basic/source/uno/namecont.cxx +++ b/basic/source/uno/namecont.cxx @@ -65,6 +65,8 @@ #include #include #include +#include +#include #include #include @@ -93,6 +95,21 @@ using com::sun::star::uno::Reference; // #i34411: Flag for error handling during migration static bool GbMigrationSuppressErrors = false; +#ifndef NDEBUG +namespace +{ +// The name->value map and the insertion-order vector are redundant views of the +// same set of names; verify they list exactly the same names, once each. +bool mapAndOrderConsistent(const std::unordered_map& rMap, + const std::vector& rOrder) +{ + if (rMap.size() != rOrder.size()) + return false; + return std::all_of(rMap.begin(), rMap.end(), [&rOrder](const auto& rEntry) + { return std::find(rOrder.begin(), rOrder.end(), rEntry.first) != rOrder.end(); }); +} +} +#endif // Implementation class NameContainer @@ -120,7 +137,8 @@ Any NameContainer::getByName( const OUString& aName ) Sequence< OUString > NameContainer::getElementNames() { - return comphelper::mapKeysToSequence(maMap); + // Return the names in insertion order. + return comphelper::containerToSequence(maNamesOrder); } sal_Bool NameContainer::hasByName( const OUString& aName ) @@ -179,7 +197,10 @@ void NameContainer::insertNoCheck(const OUString& aName, const Any& aElement, throw IllegalArgumentException(u"types do not match"_ustr, rOwner, 2); } + assert(!maMap.contains(aName) && "insertNoCheck: name already present"); maMap[aName] = aElement; + maNamesOrder.push_back(aName); + assert(mapAndOrderConsistent(maMap, maNamesOrder)); // Fire event if (maContainerListeners.getLength(guard) > 0) @@ -223,6 +244,8 @@ void NameContainer::removeByName(const OUString& aName, std::unique_locksecond; maMap.erase(aIt); + std::erase(maNamesOrder, aName); + assert(mapAndOrderConsistent(maMap, maNamesOrder)); // Fire event if (maContainerListeners.getLength(guard) > 0) diff --git a/sc/qa/extras/macros-test.cxx b/sc/qa/extras/macros-test.cxx index 2fc445f25645..03e77f566632 100644 --- a/sc/qa/extras/macros-test.cxx +++ b/sc/qa/extras/macros-test.cxx @@ -21,7 +21,9 @@ #include #include +#include #include +#include #include #include @@ -29,8 +31,11 @@ #include #include -#include +#include +#include #include +#include +#include #include using namespace ::com::sun::star; @@ -745,6 +750,40 @@ CPPUNIT_TEST_FIXTURE(ScMacrosTest, testTdf107572) } } +CPPUNIT_TEST_FIXTURE(ScMacrosTest, testCool15956) +{ + // A Basic library enumerates its modules in insertion order, and that order must survive a + // save/reload unchanged: it determines the on-disk byte layout of the library index and module + // streams, which macro signatures sign over (cool#15956). + createScDoc(); + + // Deliberately non-sorted insertion order. + const OUString order[]{ u"Gamma"_ustr, u"Alpha"_ustr, u"Delta"_ustr, u"Beta"_ustr }; + + auto checkOrder = [&order](const uno::Sequence& names) { + CPPUNIT_ASSERT(std::equal(names.begin(), names.end(), std::begin(order), std::end(order))); + }; + + auto xDocScr = mxComponent.queryThrow(); + auto xLibs = xDocScr->getBasicLibraries().queryThrow(); + auto xLibrary = xLibs->createLibrary(u"TestLibrary"_ustr); + for (const OUString& rName : order) + xLibrary->insertByName(rName, uno::Any(u"Sub "_ustr + rName + u"\nEnd Sub\n"_ustr)); + + // In memory, getElementNames() must reflect insertion order. + checkOrder(xLibrary->getElementNames()); + + saveAndReload(TestFilter::ODS); + + // After the store/reload, the reloaded library keeps the same module order; + // without insertion-order preservation it came back permuted. + xDocScr = mxComponent.queryThrow(); + xLibs = xDocScr->getBasicLibraries().queryThrow(); + xLibs->loadLibrary(u"TestLibrary"_ustr); + auto xReloaded = xLibs->getByName(u"TestLibrary"_ustr).queryThrow(); + checkOrder(xReloaded->getElementNames()); +} + CPPUNIT_TEST_FIXTURE(ScMacrosTest, testShapeLayerId) { createScDoc(); diff --git a/xmlsecurity/qa/unit/signing/data/Cool15956.ods b/xmlsecurity/qa/unit/signing/data/Cool15956.ods new file mode 100644 index 0000000000000000000000000000000000000000..624f4a37049995b0372a62e6693d9f4bfd2c49a4 GIT binary patch literal 15782 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 literal 0 HcmV?d00001 diff --git a/xmlsecurity/qa/unit/signing/signing.cxx b/xmlsecurity/qa/unit/signing/signing.cxx index f291f9e673c0..a29010ca615f 100644 --- a/xmlsecurity/qa/unit/signing/signing.cxx +++ b/xmlsecurity/qa/unit/signing/signing.cxx @@ -22,8 +22,10 @@ #include #include +#include #include #include +#include #include #include #include @@ -1260,6 +1262,40 @@ CPPUNIT_TEST_FIXTURE(SigningTest, testImplicitScriptSign) 1); } +CPPUNIT_TEST_FIXTURE(SigningTest, testCool15956) +{ + // The Basic library and module order is part of the signed macro streams (Basic/script-lc.xml + // and each Basic//script-lb.xml). Re-saving a document must keep the insertion order to + // keep macro signatures valid. + loadFromFile(u"Cool15956.ods"); + SfxBaseModel* pBaseModel = dynamic_cast(mxComponent.get()); + CPPUNIT_ASSERT(pBaseModel); + SfxObjectShell* pObjectShell = pBaseModel->GetObjectShell(); + CPPUNIT_ASSERT(pObjectShell); + SignatureState eBefore = pObjectShell->GetScriptingSignatureState(); + CPPUNIT_ASSERT(eBefore == SignatureState::OK || eBefore == SignatureState::NOTVALIDATED); + + // Load the libraries so that storing regenerates their index and module streams. + auto xScripts = mxComponent.queryThrow(); + auto xLibs = xScripts->getBasicLibraries().queryThrow(); + for (const OUString& rLib : xLibs->getElementNames()) + xLibs->loadLibrary(rLib); + + // FIXME: Error: element "document-signatures" is missing "version" attribute + skipValidation(); + + saveAndReload(TestFilter::ODS); + + pBaseModel = dynamic_cast(mxComponent.get()); + CPPUNIT_ASSERT(pBaseModel); + pObjectShell = pBaseModel->GetObjectShell(); + CPPUNIT_ASSERT(pObjectShell); + SignatureState eAfter = pObjectShell->GetScriptingSignatureState(); + // Without the NameContainer insertion-order fix the resave reordered the signed + // Basic streams and the macro signature was dropped (SignatureState::NOSIGNATURES). + CPPUNIT_ASSERT(eAfter == SignatureState::OK || eAfter == SignatureState::NOTVALIDATED); +} + #if HAVE_FEATURE_GPGVERIFY /// Test a typical ODF where all streams are GPG-signed. CPPUNIT_TEST_FIXTURE(SigningTest, testODFGoodGPG)