java-topology/defects/libreoffice/patch/libreoffice-0003-msgpool-group-dedup-quadratic.patch

44 lines
1.9 KiB
Diff

# UNDF: UNDF-2026-000000788
# UNDF: (leave blank)
# LibreOffice CWE-407: SfxSlotPool group dedup O(F*G)
#
# In sfx2/source/control/msgpool.cxx, when registering a new interface
# the code iterates over all slots (nFunc loop) and for each slot checks
# whether its GroupId is already in _vGroups via std::find(). This is
# O(F*G) where F=number of slots and G=number of groups.
#
# Fix: use an unordered_set for O(1) membership test during registration,
# keeping _vGroups as the canonical ordered list.
#
# Severity: LOW-MEDIUM — called once per interface registration at startup.
# With many modules loaded (Writer+Calc+Impress+Draw) the slot count
# can reach hundreds per interface. At F=300 slots, G=50 groups:
# 15,000 comparisons reduced to 300.
--- a/sfx2/source/control/msgpool.cxx
+++ b/sfx2/source/control/msgpool.cxx
@@ -124,14 +124,18 @@
// possibly add Interface-id and group-ids of funcs to the list of groups
if ( _pParentPool )
{
// The Groups in parent Slotpool are also known here
_vGroups.insert( _vGroups.end(), _pParentPool->_vGroups.begin(), _pParentPool->_vGroups.end() );
}
+ // Build a set for O(1) dedup during slot registration
+ std::unordered_set<SfxGroupId> aGroupSet(_vGroups.begin(), _vGroups.end());
+
for ( size_t nFunc = 0; nFunc < rInterface.Count(); ++nFunc )
{
const SfxSlot &rDef = rInterface.pSlots[nFunc];
if ( rDef.GetGroupId() != SfxGroupId::NONE &&
- std::find(_vGroups.begin(), _vGroups.end(), rDef.GetGroupId()) == _vGroups.end() )
+ aGroupSet.find(rDef.GetGroupId()) == aGroupSet.end() )
{
+ aGroupSet.insert(rDef.GetGroupId());
if (rDef.GetGroupId() == SfxGroupId::Intern)
_vGroups.insert(_vGroups.begin(), rDef.GetGroupId());
else
_vGroups.push_back(rDef.GetGroupId());
}
}
}