java-topology/defects/supertuxkart-0001/patch/supertuxkart-0001.patch
russell@unturf.com a7907f0e12 supertuxkart-0001: item_manager randomItemsForArena O(N^2) invalid_location scan
CWE-407 defect in src/items/item_manager.cpp:635. std::find on
std::vector<int> invalid_location inside retry loop inside placement
loop. Fix: std::unordered_set<int> for O(1) membership. 13.8x at N=500.

MOAD-0002 through MOAD-0005 scanned CLEAN:
- MOAD-0002 (Intertangle): standard game engine singleton pattern
- MOAD-0003 (Leaked Context): thread_local g_process_type is process-scoped
- MOAD-0004 (Logged Secret): HTTP request logging already has credential denylist
- MOAD-0005 (Thundering Herd): no shared cache patterns in network code
2026-03-31 10:09:46 -04:00

63 lines
2.5 KiB
Diff

# UNDF: UNDF-2026-000000944
--- a/src/items/item_manager.cpp
+++ b/src/items/item_manager.cpp
@@ -593,8 +593,8 @@ bool ItemManager::randomItemsForArena(const AlignedArray<btTransform>& pos)
const ArenaGraph* ag = ArenaGraph::get();
std::vector<int> used_location;
- std::vector<int> invalid_location;
+ std::unordered_set<int> invalid_location;
for (unsigned int i = 0; i < pos.size(); i++)
{
// Load all starting positions of arena, so no items will be near them
@@ -602,7 +602,7 @@ bool ItemManager::randomItemsForArena(const AlignedArray<btTransform>& pos)
ag->findRoadSector(pos[i].getOrigin(), &node, NULL, true);
assert(node != -1);
used_location.push_back(node);
- invalid_location.push_back(node);
+ invalid_location.insert(node);
}
const unsigned int ALL_NODES = ag->getNumNodes();
@@ -620,7 +620,6 @@ bool ItemManager::randomItemsForArena(const AlignedArray<btTransform>& pos)
while(true)
{
- if (used_location.size() - pos.size() +
- invalid_location.size() == ALL_NODES)
+ if (used_location.size() - pos.size() + invalid_location.size() == ALL_NODES)
{
Log::warn("[ItemManager]","Can't place more random items! "
"Use default item location.");
@@ -632,9 +631,7 @@ bool ItemManager::randomItemsForArena(const AlignedArray<btTransform>& pos)
const int node = number % ALL_NODES;
// Check if tried
- std::vector<int>::iterator it = std::find(invalid_location.begin(),
- invalid_location.end(), node);
- if (it != invalid_location.end())
+ if (invalid_location.count(node))
continue;
// Check if near edge
if (ag->getNode(node)->isNearEdge())
{
- invalid_location.push_back(node);
+ invalid_location.insert(node);
continue;
}
// Check if too close
@@ -654,12 +651,12 @@ bool ItemManager::randomItemsForArena(const AlignedArray<btTransform>& pos)
if (found)
{
chosen_node = node;
- invalid_location.push_back(node);
+ invalid_location.insert(node);
random_numbers.push_back(number);
break;
}
else
- invalid_location.push_back(node);
+ invalid_location.insert(node);
}
assert(chosen_node != -1);