jitsi-meet-0003: av-moderation pendingAudio/Video/Desktop Array.find() dedup O(P^2) in large moderated meetings — 249.5x op-count at P=500, 138.5x measured at P=2000. Fix: Map<id, participant> for O(1) dedup. jitsi-meet-0004: visitors middleware delta Array.findIndex() per update O(U*V) in large broadcast events — 15x at V=5000 U=1000. Fix: Map-based apply-delta O(1) per join/leave. solvespace-0002: VRML export colours_present std::vector + find_if O(T*C) per triangle — 250x op-count at T=50k C=500. Fix: unordered_map keyed by ToPackedInt() RGBA uint32. MOAD-0002/0003/0004/0005: CLEAN for both targets. All 13 unit tests PASS.
2.5 KiB
solvespace-0002 — MOAD-0001 CWE-407
Location
src/export.cpp, ExportWrlMeshes() (VRML/WRL export), lines 1225-1240
Pattern
O(T × C): During VRML mesh export, Solvespace builds a per-shape colour palette
by iterating every triangle and scanning a std::vector<RgbaColor> to check
whether our triangle's colour is already present:
std::vector<int> triangle_colour_ids;
std::vector<RgbaColor> colours_present;
for(const auto & sp : op.second) { // outer: spans
for(const auto & tr : sp) { // inner: triangles O(T)
const auto colour_itr = std::find_if(
colours_present.begin(), colours_present.end(),
[&](const RgbaColor & c) {
return c.Equals(tr.meta.color); // O(C) per triangle
});
if(colour_itr == colours_present.end()) {
colours_present.insert(colours_present.end(), tr.meta.color);
triangle_colour_ids.push_back(colours_present.size() - 1);
} else {
triangle_colour_ids.push_back(colour_itr - colours_present.begin());
}
}
}
Each triangle triggers a full O(C) walk of colours_present. Total cost: O(T × C).
Severity
MEDIUM-HIGH. A mechanical assembly export with:
- T = 100,000 triangles (typical for a detailed 3D model)
- C = 64 distinct colours (per-part colour coding is common)
Results in 6,400,000 comparisons vs 100,000 with an unordered_map.
RgbaColor is a packed uint32_t (four uint8_t fields: red, green, blue, alpha).
Our hash map key is color.ToPackedIntBGRA() (already defined in our codebase).
Fix is a single-line unordered_map<uint32_t, int> substitution. 64x overhead at
typical export size.
Fix
Replace std::vector<RgbaColor> colours_present with
std::unordered_map<uint32_t, int> colour_to_index. Key: tr.meta.color.ToPackedIntBGRA().
Value: index into our VRML color array. Membership test becomes colour_to_index.count(key)
(O(1)). The array output for VRML is built in insertion order from our map values.
ToPackedIntBGRA() is already defined in dsc.h line 649 — no new infrastructure needed.
All 5 MOADs
- MOAD-0001: CONFIRMED (this defect)
- MOAD-0002: CLEAN (SS/SK globals are intentional single-user desktop CAD singletons; no coupling to new subsystems)
- MOAD-0003: CLEAN (single-threaded tool; no request-scoped context leakage)
- MOAD-0004: CLEAN (no network features; no credentials handled anywhere)
- MOAD-0005: CLEAN (single-process, single-threaded; no concurrent cache access possible)