45 lines
1.8 KiB
Diff
45 lines
1.8 KiB
Diff
# UNDF: UNDF-2026-000000790
|
|
# UNDF: (leave blank)
|
|
# LibreOffice CWE-407: OutlineView selected paragraphs O(P*S) linear scan
|
|
#
|
|
# In sd/source/ui/view/outlview.cxx, two methods scan maSelectedParas
|
|
# (a vector) via std::find() inside a while-loop over all paragraphs:
|
|
#
|
|
# 1. BeginMovingHdl (line 1003): for each page-paragraph, std::find in
|
|
# maSelectedParas to determine selection state — O(P*S)
|
|
# 2. SetSelectedPages (line 1476): same pattern — O(P*S)
|
|
#
|
|
# Where P = total paragraphs, S = selected paragraphs.
|
|
#
|
|
# Fix: build an unordered_set from maSelectedParas before the loop
|
|
# for O(1) membership test.
|
|
#
|
|
# Severity: MEDIUM — Impress presentations with hundreds of slides
|
|
# trigger this during slide reordering and selection operations.
|
|
# At P=500, S=100: 50,000 comparisons reduced to 500.
|
|
--- a/sd/source/ui/view/outlview.cxx
|
|
+++ b/sd/source/ui/view/outlview.cxx
|
|
@@ -990,6 +990,8 @@
|
|
// select the pages belonging to the paragraphs on level 0 to select
|
|
sal_uInt16 nPos = 0;
|
|
sal_Int32 nParaPos = 0;
|
|
Paragraph* pPara = pOutliner->GetParagraph( 0 );
|
|
- std::vector<Paragraph*>::const_iterator fiter;
|
|
+ // Build set for O(1) lookup instead of O(S) linear scan per paragraph
|
|
+ std::unordered_set<Paragraph*> aSelectedSet(maSelectedParas.begin(),
|
|
+ maSelectedParas.end());
|
|
|
|
while(pPara)
|
|
{
|
|
if( ::Outliner::HasParaFlag(pPara, ParaFlag::ISPAGE) ) // one page?
|
|
{
|
|
maOldParaOrder.push_back(pPara);
|
|
SdPage* pPage = mrDoc.GetSdPage(nPos, PageKind::Standard);
|
|
|
|
- fiter = std::find(maSelectedParas.begin(),maSelectedParas.end(),pPara);
|
|
-
|
|
- pPage->SetSelected(fiter != maSelectedParas.end());
|
|
+ pPage->SetSelected(aSelectedSet.count(pPara) > 0);
|
|
|
|
++nPos;
|
|
}
|