java-topology/defects/kdenlive/patch/kdenlive-0005-previewmanager-chunk-lists-linear-contains.patch

57 lines
2.3 KiB
Diff

# UNDF: UNDF-2026-000000835
# UNDF: (leave blank)
# Defect: kdenlive-0005
# Component: src/timeline2/view/previewmanager.h + previewmanager.cpp
# Pattern: CWE-407 — m_renderedChunks/m_dirtyChunks QVariantList with .contains() in loops
# Severity: MEDIUM — O(D*M) chunk dedup in reloadChunks, O(N*(R+D)) in invalidatePreview/addPreviewRange/gotChunks
# Fix: Maintain shadow QSet<int> for O(1) membership tests on m_renderedChunks and m_dirtyChunks
--- a/src/timeline2/view/previewmanager.h
+++ b/src/timeline2/view/previewmanager.h
@@ -146,6 +146,8 @@
QVariantList m_renderedChunks;
QVariantList m_dirtyChunks;
QList<int> m_dirtyChunksToRemove;
+ QSet<int> m_renderedChunksSet; // shadow set for O(1) .contains()
+ QSet<int> m_dirtyChunksSet; // shadow set for O(1) .contains()
--- a/src/timeline2/view/previewmanager.cpp
+++ b/src/timeline2/view/previewmanager.cpp
// Everywhere m_dirtyChunks or m_renderedChunks is modified, also update the shadow set:
//
// INSERT:
// m_dirtyChunks << i;
-// → if (!m_dirtyChunksSet.contains(i)) { m_dirtyChunks << i; m_dirtyChunksSet.insert(i); }
+// → if (!m_dirtyChunksSet.contains(i)) { m_dirtyChunks << i; m_dirtyChunksSet.insert(i); }
//
// REMOVE:
// m_renderedChunks.removeAll(frame);
// → m_renderedChunks.removeAll(frame); m_renderedChunksSet.remove(frame.toInt());
//
// CONTAINS checks (the CWE-407 sites):
//
// Line ~188 (reloadChunks):
-// if (!m_dirtyChunks.contains(i))
+// if (!m_dirtyChunksSet.contains(i.toInt()))
//
// Line ~472 (invalidatePreview redo lambda):
-// if (m_renderedChunks.contains(frame))
+// if (m_renderedChunksSet.contains(frame.toInt()))
//
// Line ~519 (addPreviewRange):
-// if (!m_renderedChunks.contains(frame) && !m_dirtyChunks.contains(frame))
+// if (!m_renderedChunksSet.contains(frame) && !m_dirtyChunksSet.contains(frame))
//
// Line ~549 (redo lambda):
-// if (m_renderedChunks.contains(frame))
+// if (m_renderedChunksSet.contains(frame.toInt()))
//
// Line ~773 (gotChunks):
-// if (m_renderedChunks.contains(i))
+// if (m_renderedChunksSet.contains(i))
//
-// if (!m_dirtyChunks.contains(val))
+// if (!m_dirtyChunksSet.contains(i))
//
// CLEAR sites:
// m_renderedChunks.clear(); → also m_renderedChunksSet.clear();
// m_dirtyChunks.clear(); → also m_dirtyChunksSet.clear();