34 lines
1.7 KiB
Markdown
34 lines
1.7 KiB
Markdown
# Krita — CWE-407 Scan Result: CLEAN
|
|
|
|
**Date:** 2026-03-30
|
|
**Scanner:** agent blackops
|
|
**Scope:** libs/ (image, flake, ui, resources, global, pigment, command, widgetutils), plugins/
|
|
|
|
## Summary
|
|
|
|
Krita is clean of CWE-407 algorithmic complexity defects. The codebase
|
|
consistently uses QHash/QMap/QSet for membership tests and lookup operations.
|
|
Where QList/QVector linear scans appear, they operate on inherently small
|
|
collections (selected shapes, layer counts, composite op IDs) and are not
|
|
data-proportional.
|
|
|
|
## Key observations
|
|
|
|
- `KisNodeDummiesGraph.m_dummiesMap`: QHash<KisNodeSP, KisNodeDummy*> for node lookups
|
|
- `KisResourceLocator`: QHash-based caches for resources and tags
|
|
- `KisMemoryLeakTracker`: QHash for reference tracking
|
|
- `SharedCache.*DeletedDuringPrewarm`: HashSet for prewarm dedup
|
|
- `KoSelection::isSelected()`: std::find on selectedShapes list, but called per-click, not in loops
|
|
- `KisWatershedWorker.groups[].levels`: QMap for level lookup — O(log N)
|
|
|
|
Minor findings (no defect):
|
|
- `KisNodeDummy::nextSibling/prevSibling`: indexOf on parent->m_children QList, O(C) per call, but
|
|
C is the number of sibling layers (typically <100) and not called in inner loops
|
|
- `KisSavedMacroCommand::mergeWith`: QVector::contains for skipWhenOverride, but skip list is tiny
|
|
and called once per undo merge
|
|
- `kis_layer_utils::scanForLastLayer`: KisNodeList::contains inside sibling walk, but N is the
|
|
number of layers selected for delete (typically <20)
|
|
- `kis_layer_utils::CleanUpNodes::findPerfectParent`: KisNodeList::contains inside parent walk,
|
|
O(D*N) where D is tree depth (~10) and N is nodes to delete (~20), runs once per merge
|
|
|
|
No data-proportional linear scans inside loops found.
|