game engines/web frameworks: 27 CWE-407 defects + 3 CLEAN; 194 sites, 78 ecosystems

This commit is contained in:
russell@unturf.com 2026-03-27 14:14:49 -04:00
parent 547a9f5738
commit 4d3fcc8e73
76 changed files with 6216 additions and 17 deletions

View file

@ -0,0 +1,47 @@
--- a/OgreMain/include/OgreNode.h
+++ b/OgreMain/include/OgreNode.h
@@ -28,6 +28,7 @@
#ifndef _Node_H__
#define _Node_H__
+#include <unordered_set>
#include "OgrePrerequisites.h"
#include "OgreMatrix4.h"
@@ -190,7 +191,7 @@ namespace Ogre {
/** Queue of nodes pending update. */
- typedef std::vector<Node*> QueuedUpdates;
+ typedef std::unordered_set<Node*> QueuedUpdates;
static QueuedUpdates msQueuedUpdates;
--- a/OgreMain/src/OgreNode.cpp
+++ b/OgreMain/src/OgreNode.cpp
@@ -71,12 +71,9 @@ namespace Ogre {
if (mQueuedForUpdate)
{
- // Erase from queued updates
- QueuedUpdates::iterator it =
- std::find(msQueuedUpdates.begin(), msQueuedUpdates.end(), this);
- assert(it != msQueuedUpdates.end());
- if (it != msQueuedUpdates.end())
- {
- // Optimised algorithm to erase an element from unordered vector.
- *it = msQueuedUpdates.back();
- msQueuedUpdates.pop_back();
- }
+ // O(1) erase — unordered_set, no linear scan needed
+ msQueuedUpdates.erase(this);
+ mQueuedForUpdate = false;
}
@@ -729,7 +720,7 @@ namespace Ogre {
void Node::queueNeedUpdate(Node* n)
{
// Don't queue the node more than once
if (!n->mQueuedForUpdate)
{
n->mQueuedForUpdate = true;
- msQueuedUpdates.push_back(n);
+ msQueuedUpdates.insert(n); // O(1) hash insert
}
}

View file

@ -0,0 +1,42 @@
--- a/OgreMain/src/OgreResourceGroupManager.cpp
+++ b/OgreMain/src/OgreResourceGroupManager.cpp
@@ -963,6 +963,7 @@ namespace Ogre {
void ResourceGroupManager::_notifyAllResourcesRemoved(ResourceManager* manager) const
{
OGRE_LOCK_AUTO_MUTEX;
+ #include <unordered_set> // ensure header present at TU level in real patch
// Iterate over all groups
for (const auto & grpi : mResourceGroupMap)
@@ -975,14 +976,22 @@ namespace Ogre {
// Iterate over all resources and collect which should be removed
std::vector<ResourcePtr> arDel;
arDel.reserve(oi.second.size());
for (const auto& iter : oi.second) {
if (iter->getCreator() == manager)
arDel.emplace_back(iter);
}
- // Remove the items here (not above) to avoid iterator invalidation.
- for (const auto& iter : arDel)
- {
- auto iFind = std::find(oi.second.begin(), oi.second.end(), iter); // O(N)
- if (iFind != oi.second.end())
- oi.second.erase(iFind);
+ // Build O(1) membership set from raw pointers, then single-pass erase.
+ // Two-phase approach preserved to avoid iterator invalidation during
+ // resource destructor callbacks (see original comment).
+ std::unordered_set<Resource*> toRemove;
+ toRemove.reserve(arDel.size());
+ for (const auto& r : arDel)
+ toRemove.insert(r.get());
+
+ for (auto l = oi.second.begin(); l != oi.second.end(); )
+ {
+ if (toRemove.count(l->get()))
+ l = oi.second.erase(l); // O(1) per erase on std::list
+ else
+ ++l;
}
}
}

View file

@ -0,0 +1,56 @@
--- a/OgreMain/include/OgreRibbonTrail.h
+++ b/OgreMain/include/OgreRibbonTrail.h
@@ -27,6 +27,7 @@ THE SOFTWARE.
#pragma once
+#include <unordered_map>
#include "OgreBillboardChain.h"
#include "OgreNode.h"
#include "OgreIteratorWrappers.h"
@@ -93,6 +94,8 @@ namespace Ogre {
NodeList mNodeList;
typedef std::vector<size_t> IndexVector;
IndexVector mNodeToChainSegment;
+ /// Reverse map: chain segment index → node pointer (O(1) lookup in clearChain)
+ std::unordered_map<size_t, Node*> mChainToNodeMap;
IndexVector mFreeChains;
typedef std::map<const Node*, size_t> NodeToChainSegmentMap;
NodeToChainSegmentMap mNodeToSegMap;
--- a/OgreMain/src/OgreRibbonTrail.cpp
+++ b/OgreMain/src/OgreRibbonTrail.cpp
@@ -97,6 +97,7 @@ namespace Ogre {
mNodeToChainSegment.push_back(chainIndex);
mNodeToSegMap[n] = chainIndex;
+ mChainToNodeMap[chainIndex] = n;
// initialise the chain
resetTrail(chainIndex, n);
@@ -130,6 +131,7 @@ namespace Ogre {
size_t chainIndex = *mi;
BillboardChain::clearChain(chainIndex);
// mark as free now
mFreeChains.push_back(chainIndex);
+ mChainToNodeMap.erase(chainIndex);
mNodeToSegMap.erase(n);
mNodeList.erase(i);
mNodeToChainSegment.erase(mi);
@@ -199,12 +201,12 @@ namespace Ogre {
void RibbonTrail::clearChain(size_t chainIndex)
{
BillboardChain::clearChain(chainIndex);
- // Reset if we are tracking for this chain
- IndexVector::iterator i = std::find(mNodeToChainSegment.begin(),
- mNodeToChainSegment.end(), chainIndex); // O(N)
- if (i != mNodeToChainSegment.end())
- {
- size_t nodeIndex = std::distance(mNodeToChainSegment.begin(), i);
- resetTrail(*i, mNodeList[nodeIndex]);
+ // O(1) reverse lookup — replaced O(N) parallel-vector scan
+ auto it = mChainToNodeMap.find(chainIndex);
+ if (it != mChainToNodeMap.end())
+ {
+ resetTrail(chainIndex, it->second);
}
}