From: Caolán McNamara Date: Sun, 26 Apr 2026 17:48:52 +0000 (+0000) Subject: [PATCH] drop malformed duplicate-id calc change track actions X-Git-Tag: archive/raspbian/4%25.2.3-2+rpi1+deb13u5^2~1 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=6878526088f54910953c1a5215a89d525920502a;p=libreoffice.git [PATCH] drop malformed duplicate-id calc change track actions Signed-off-by: Caolán McNamara Change-Id: I0d532eb84d122e39ce71e94b4760b94cd636eeea Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/1691 Tested-by: Jenkins CPCI Reviewed-by: Miklos Vajna (cherry picked from commit b5b56a2239369e45d7fac2ea965558a1f337b602) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/205091 Reviewed-by: Xisco Fauli Tested-by: Jenkins (cherry picked from commit a20ae7b5f80a45e49a47ce22f5e92749cd9816a0) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/205101 Gbp-Pq: Name CVE-2026-8358.diff --- diff --git a/sc/inc/chgtrack.hxx b/sc/inc/chgtrack.hxx index 9e3aed17aa5..7c1889e18ba 100644 --- a/sc/inc/chgtrack.hxx +++ b/sc/inc/chgtrack.hxx @@ -1115,7 +1115,8 @@ public: sal_uLong AddLoadedGenerated( const ScCellValue& rNewCell, const ScBigRange& aBigRange, const OUString& sNewValue ); // only to use in the XML import - void AppendLoaded( std::unique_ptr pAppend ); // this is only for the XML import public, it should be protected + // returns false if the action number is already in use, in which case the new duplicate is dropped + bool AppendLoaded( std::unique_ptr pAppend ); // this is only for the XML import public, it should be protected void SetActionMax(sal_uLong nTempActionMax) { nActionMax = nTempActionMax; } // only to use in the XML import diff --git a/sc/source/core/tool/chgtrack.cxx b/sc/source/core/tool/chgtrack.cxx index f5ccfd579af..ee3b850e0bd 100644 --- a/sc/source/core/tool/chgtrack.cxx +++ b/sc/source/core/tool/chgtrack.cxx @@ -2315,10 +2315,12 @@ void ScChangeTrack::MasterLinks( ScChangeAction* pAppend ) } } -void ScChangeTrack::AppendLoaded( std::unique_ptr pActionParam ) +bool ScChangeTrack::AppendLoaded( std::unique_ptr pActionParam ) { + auto [it, inserted] = aMap.insert(std::make_pair(pActionParam->GetActionNumber(), pActionParam.get())); + if (!inserted) + return false; ScChangeAction* pAppend = pActionParam.release(); - aMap.insert( ::std::make_pair( pAppend->GetActionNumber(), pAppend ) ); if ( !pLast ) pFirst = pLast = pAppend; else @@ -2328,6 +2330,7 @@ void ScChangeTrack::AppendLoaded( std::unique_ptr pActionParam ) pLast = pAppend; } MasterLinks( pAppend ); + return true; } void ScChangeTrack::Append( ScChangeAction* pAppend, sal_uLong nAction ) diff --git a/sc/source/filter/xml/XMLChangeTrackingImportHelper.cxx b/sc/source/filter/xml/XMLChangeTrackingImportHelper.cxx index 1bc9c21b0e6..b4b747f4ef3 100644 --- a/sc/source/filter/xml/XMLChangeTrackingImportHelper.cxx +++ b/sc/source/filter/xml/XMLChangeTrackingImportHelper.cxx @@ -719,8 +719,10 @@ void ScXMLChangeTrackingImportHelper::CreateChangeTrack(ScDocument* pDoc) // old files didn't store nanoseconds, disable until encountered pTrack->SetTimeNanoSeconds( false ); - for (const auto & rAction : aActions) + auto aItr = aActions.begin(); + while (aItr != aActions.end()) { + const auto& rAction = *aItr; std::unique_ptr pAction; switch (rAction->nActionType) @@ -764,17 +766,20 @@ void ScXMLChangeTrackingImportHelper::CreateChangeTrack(ScDocument* pDoc) } } - if (pAction) - pTrack->AppendLoaded(std::move(pAction)); + // Malformed documents can repeat the same XML id across actions. If + // this happens drop entries whose action number is already in the track. + if (pAction && pTrack->AppendLoaded(std::move(pAction))) + ++aItr; else { - OSL_FAIL("no action"); + SAL_WARN("sc.filter", "Dropping malformed change track entry"); + aItr = aActions.erase(aItr); } } if (pTrack->GetLast()) pTrack->SetActionMax(pTrack->GetLast()->GetActionNumber()); - auto aItr = aActions.begin(); + aItr = aActions.begin(); while (aItr != aActions.end()) { SetDependencies(aItr->get(), *pDoc);