0ad-0001 CCmpObstructionManager dirty shapes vector+std::find O(N*D) HIGH 4.1x 0ad-0002 CCmpRangeManager m_ModifiedEntities vector+std::find O(E*M) HIGH 25.8x 0ad-0003 CCmpTemplateManager FindUsedTemplates vector+std::find O(T^2) MEDIUM 5.9x 0ad-0004 XmppClient+NetServer lobby auth token logged verbatim CWE-312 MEDIUM MOAD-0002 (Intertangle): g_ globals are deliberate single-thread game arch, CLEAN MOAD-0003 (Leaked Context): thread_local properly scoped, CLEAN MOAD-0005 (Thundering Herd): single-threaded sim, no cache stampede, CLEAN 4/4 unit tests PASS, UNDF 956-959
73 lines
3.4 KiB
Diff
73 lines
3.4 KiB
Diff
# UNDF: UNDF-2026-000000956
|
|
--- a/source/simulation2/components/CCmpObstructionManager.cpp
|
|
+++ b/source/simulation2/components/CCmpObstructionManager.cpp
|
|
@@ -1,6 +1,7 @@
|
|
// CWE-407: CCmpObstructionManager dirty shape tracking uses std::vector with
|
|
// std::find for dedup, causing O(N*D) per-frame cost where N = nearby shapes
|
|
// and D = dirty list size. In large battles (200v200), hundreds of shapes
|
|
// move per frame, making this O(N^2). Fix: use std::unordered_set for O(1) lookup.
|
|
+#include <unordered_set>
|
|
|
|
// --- Declaration change ---
|
|
@@ -525,8 +526,8 @@
|
|
// Dynamic updates for the long-range pathfinder
|
|
GridUpdateInformation m_UpdateInformations;
|
|
// These vectors might contain shapes that were deleted
|
|
- std::vector<u32> m_DirtyStaticShapes;
|
|
- std::vector<u32> m_DirtyUnitShapes;
|
|
+ std::unordered_set<u32> m_DirtyStaticShapes;
|
|
+ std::unordered_set<u32> m_DirtyUnitShapes;
|
|
|
|
// --- MakeDirtyStatic ---
|
|
@@ -584,8 +585,7 @@
|
|
- if (std::find(m_DirtyStaticShapes.begin(), m_DirtyStaticShapes.end(), index) == m_DirtyStaticShapes.end())
|
|
- m_DirtyStaticShapes.push_back(index);
|
|
+ m_DirtyStaticShapes.insert(index);
|
|
|
|
// All shapes overlapping the updated part of the grid should be dirtied too.
|
|
@@ -599,12 +599,10 @@
|
|
std::vector<u32> staticsNear;
|
|
m_StaticSubdivision.GetInRange(staticsNear, center - hbox - expand*2, center + hbox + expand*2);
|
|
for (u32& staticId : staticsNear)
|
|
- if (std::find(m_DirtyStaticShapes.begin(), m_DirtyStaticShapes.end(), staticId) == m_DirtyStaticShapes.end())
|
|
- m_DirtyStaticShapes.push_back(staticId);
|
|
+ m_DirtyStaticShapes.insert(staticId);
|
|
|
|
std::vector<u32> unitsNear;
|
|
m_UnitSubdivision.GetInRange(unitsNear, center - hbox - expand*2, center + hbox + expand*2);
|
|
for (u32& unitId : unitsNear)
|
|
- if (std::find(m_DirtyUnitShapes.begin(), m_DirtyUnitShapes.end(), unitId) == m_DirtyUnitShapes.end())
|
|
- m_DirtyUnitShapes.push_back(unitId);
|
|
+ m_DirtyUnitShapes.insert(unitId);
|
|
|
|
// --- MakeDirtyUnit ---
|
|
@@ -624,8 +622,7 @@
|
|
- if (std::find(m_DirtyUnitShapes.begin(), m_DirtyUnitShapes.end(), index) == m_DirtyUnitShapes.end())
|
|
- m_DirtyUnitShapes.push_back(index);
|
|
+ m_DirtyUnitShapes.insert(index);
|
|
|
|
@@ -637,12 +634,10 @@
|
|
std::vector<u32> staticsNear;
|
|
m_StaticSubdivision.GetNear(staticsNear, center, shape.clearance + m_MaxClearance*2);
|
|
for (u32& staticId : staticsNear)
|
|
- if (std::find(m_DirtyStaticShapes.begin(), m_DirtyStaticShapes.end(), staticId) == m_DirtyStaticShapes.end())
|
|
- m_DirtyStaticShapes.push_back(staticId);
|
|
+ m_DirtyStaticShapes.insert(staticId);
|
|
|
|
std::vector<u32> unitsNear;
|
|
m_UnitSubdivision.GetNear(unitsNear, center, shape.clearance + m_MaxClearance*2);
|
|
for (u32& unitId : unitsNear)
|
|
- if (std::find(m_DirtyUnitShapes.begin(), m_DirtyUnitShapes.end(), unitId) == m_DirtyUnitShapes.end())
|
|
- m_DirtyUnitShapes.push_back(unitId);
|
|
+ m_DirtyUnitShapes.insert(unitId);
|
|
|
|
// --- RasterizeHelper ---
|
|
@@ -1116,7 +1111,7 @@
|
|
- if (!fullUpdate && std::find(m_DirtyStaticShapes.begin(), m_DirtyStaticShapes.end(), pair.first) == m_DirtyStaticShapes.end())
|
|
+ if (!fullUpdate && m_DirtyStaticShapes.find(pair.first) == m_DirtyStaticShapes.end())
|
|
continue;
|
|
|
|
@@ -1139,7 +1134,7 @@
|
|
- if (!fullUpdate && std::find(m_DirtyUnitShapes.begin(), m_DirtyUnitShapes.end(), pair.first) == m_DirtyUnitShapes.end())
|
|
+ if (!fullUpdate && m_DirtyUnitShapes.find(pair.first) == m_DirtyUnitShapes.end())
|
|
continue;
|