java-topology/whitepaper/outreach/krita-0001.md
russell@unturf.com 652608142a feat: close outreach doc gap — 276 docs (batches 11-16)
All projects with patches now have outreach docs. 276 new docs covering
CWE-407, CWE-312, CWE-362 across C, C++, Java, Python, Go, Rust, C#,
PHP, Ruby, JavaScript, Dart, Erlang, R, and more.

Outreach gap: 276 -> 0.
2026-04-15 13:57:42 -04:00

2.6 KiB
Raw Permalink Blame History

Krita — CWE-407 Disclosure Brief (krita-0001)

2026-04-13 · Patch available — awaiting upstream merge

Finding

One O(N²) defect in Krita's layer docker. The togglePropertyRecursive() method in NodeDelegate uses QList<QModelIndex>::contains() for membership testing against a list of selected items, producing O(N²) per property toggle click where N = layer count.

The Defect

krita-0001 (PATCHED — MEDIUM): plugins/dockers/layerdocker/NodeDelegate.cpp:548

// togglePropertyRecursive walks all children recursively, checking:
void NodeDelegate::Private::togglePropertyRecursive(
    const QModelIndex &root,
    const OptionalProperty &clickedProperty,
    const QList<QModelIndex> &items,  // items list passed from caller
    StasisOperation record, bool mode)
{
    // For each child node in tree:
    // items.contains(child) — O(N) per child
}

The items parameter is a QList<QModelIndex>. The contains() call is O(N) per node in the recursive walk. With N layers total, the recursive walk visits up to N nodes, each checking membership against a list of up to N items: O(N²).

Complexity Proof

At N=500 layers:

  • Defective: 500 × 250 (avg) = 125,000 comparisons per toggle click
  • Fixed: 500 × O(1) QSet lookups = 500 operations
  • ~250× op reduction.

Impact

Krita is a professional digital painting application used by artists and animators worldwide. Complex artworks commonly have hundreds of layers. Toggling layer properties (visibility, lock, alpha lock) with modifier keys to affect multiple layers triggers the quadratic path.

The Fix

Convert the QList<QModelIndex> to QSet<QModelIndex> before passing to the recursive function:

// Before
togglePropertyRecursive(root, clickedProperty, items, record, mode);

// After
QSet<QModelIndex> itemsSet(items.begin(), items.end());
togglePropertyRecursive(root, clickedProperty, itemsSet, record, mode);

Patch

Fix available: defects/krita-0001/patch/krita-0001.patch

Two-file patch across NodeDelegate.h and NodeDelegate.cpp. Changes parameter type and adds conversion at call site. ~250× speedup at 500 layers.

What We Ask

A patch is ready for review.

  1. Confirm receipt and assign a GitHub issue reference (KDE/krita).
  2. Assess severity — fires on every multi-layer property toggle click.
  3. Coordinate a disclosure date — we are targeting 90 days from first contact.
  4. We will credit the Krita team in the public disclosure. Preferred acknowledgment format welcome.

Contact: see cover email. This brief is confidential until coordinated disclosure.