java-topology/defects/openmw-0003/patch/openmw-0003.patch
russell@unturf.com 4e3dcc8d2a openmw: 4 CWE-407 defects, MOAD 0002-0005 CLEAN
openmw-0001: pathgrid.cpp Tarjan SCC std::find(mSCCStack) O(V^2), 2.3x (HIGH)
openmw-0002: pathgrid.cpp A* openset std::find O(V*E), 4.4x op-count (HIGH)
openmw-0003: cellstore.cpp mMovedRefs std::find O(R*M), 15.6x (MEDIUM)
openmw-0004: objectpaging.cpp mMovedRefs std::find O(R*M), 4.9x (MEDIUM)

MOAD-0002 (Intertangle): CLEAN, typical game engine global state
MOAD-0003 (Leaked Context): CLEAN, no thread_local identity carriers
MOAD-0004 (Logged Secret): CLEAN, game engine has no credentials
MOAD-0005 (Thundering Herd): CLEAN, no unsynchronized cache patterns

8/8 unit tests PASS.
2026-03-31 12:11:13 -04:00

54 lines
2.2 KiB
Diff

# UNDF: UNDF-2026-000000965
--- a/apps/openmw/mwworld/cellstore.cpp
+++ b/apps/openmw/mwworld/cellstore.cpp
@@ -1,4 +1,5 @@
#include "cellstore.hpp"
+#include <unordered_set>
// ...existing includes...
@@ -745,6 +746,12 @@
// Build mMovedRefs lookup set once before iterating references.
+ std::unordered_set<ESM::RefNum, ESM::RefNum::HashPair> movedRefSet;
+ movedRefSet.reserve(cell.mMovedRefs.size());
+ for (const auto& moved : cell.mMovedRefs)
+ movedRefSet.insert(moved.mRefNum);
+
// ...existing code for loading references...
for (size_t i = 0; i < cell.mContextList.size(); i++)
{
@@ -770,8 +777,7 @@
if (deleted || moved)
continue;
- // Don't list reference if it was moved to a different cell.
- ESM::MovedCellRefTracker::const_iterator iter
- = std::find(cell.mMovedRefs.begin(), cell.mMovedRefs.end(), ref.mRefNum);
- if (iter != cell.mMovedRefs.end())
+ // Don't list reference if it was moved to a different cell (O(1) lookup).
+ if (movedRefSet.count(ref.mRefNum))
{
continue;
}
@@ -853,8 +859,13 @@
+ // Build mMovedRefs lookup set once before iterating references.
+ std::unordered_set<ESM::RefNum, ESM::RefNum::HashPair> movedRefSet2;
+ movedRefSet2.reserve(cell.mMovedRefs.size());
+ for (const auto& moved : cell.mMovedRefs)
+ movedRefSet2.insert(moved.mRefNum);
+
for (size_t i = 0; i < cell.mContextList.size(); i++)
{
@@ -862,8 +873,7 @@
if (moved)
continue;
- // Don't load reference if it was moved to a different cell.
- ESM::MovedCellRefTracker::const_iterator iter
- = std::find(cell.mMovedRefs.begin(), cell.mMovedRefs.end(), ref.mRefNum);
- if (iter != cell.mMovedRefs.end())
+ // Don't load reference if it was moved to a different cell (O(1) lookup).
+ if (movedRefSet2.count(ref.mRefNum))
{
continue;
}