cataclysm-0001: overmap_ui search dedup vector O(P*M), 79x cataclysm-0002: dependency_tree dedup vector O(N^2), 2x cataclysm-0003: surroundings_menu item/terfurn dedup O(N^2), 9x
74 lines
2.8 KiB
Diff
74 lines
2.8 KiB
Diff
# UNDF: UNDF-2026-000000936
|
|
--- a/src/dependency_tree.cpp
|
|
+++ b/src/dependency_tree.cpp
|
|
@@ -1,5 +1,6 @@
|
|
#include "dependency_tree.h"
|
|
|
|
#include <algorithm>
|
|
+#include <unordered_set>
|
|
#include <array>
|
|
#include <ostream>
|
|
|
|
@@ -103,14 +104,15 @@
|
|
void dependency_node::inherit_errors()
|
|
{
|
|
std::stack<dependency_node * > nodes_to_check;
|
|
std::set<mod_id> nodes_visited;
|
|
|
|
// ... (BFS traversal) ...
|
|
// BEFORE (CWE-407): cur_errors is a copy of all_errors[error_type],
|
|
// std::find scans it linearly for each node_error. O(E*N).
|
|
+ // Also note: cur_errors is a stale copy, dedup is partially broken.
|
|
//
|
|
- std::vector<std::string> cur_errors = all_errors[error_type];
|
|
- for( auto &node_error : node_errors ) {
|
|
- if( std::find( cur_errors.begin(), cur_errors.end(), node_error ) ==
|
|
- cur_errors.end() ) {
|
|
+ std::unordered_set<std::string> cur_errors_set(
|
|
+ all_errors[error_type].begin(), all_errors[error_type].end() );
|
|
+ for( const auto &node_error : node_errors ) {
|
|
+ if( cur_errors_set.find( node_error ) == cur_errors_set.end() ) {
|
|
all_errors[cerror.first].push_back( node_error );
|
|
+ cur_errors_set.insert( node_error );
|
|
}
|
|
}
|
|
|
|
@@ -157,6 +159,7 @@
|
|
std::vector<dependency_node *> dependency_node::get_dependencies_as_nodes()
|
|
{
|
|
std::vector<dependency_node *> dependencies;
|
|
std::vector<dependency_node *> ret;
|
|
+ std::unordered_set<dependency_node *> ret_seen;
|
|
std::set<mod_id> found;
|
|
|
|
// ... (BFS collection into dependencies) ...
|
|
@@ -188,8 +191,9 @@
|
|
// BEFORE (CWE-407): std::find on ret vector for dedup, O(N^2)
|
|
for( std::vector<dependency_node *>::reverse_iterator it =
|
|
dependencies.rbegin();
|
|
it != dependencies.rend(); ++it ) {
|
|
- if( std::find( ret.begin(), ret.end(), *it ) == ret.end() ) {
|
|
+ if( ret_seen.find( *it ) == ret_seen.end() ) {
|
|
ret.push_back( *it );
|
|
+ ret_seen.insert( *it );
|
|
}
|
|
}
|
|
|
|
@@ -216,6 +220,7 @@
|
|
std::vector<dependency_node *> dependency_node::get_dependents_as_nodes()
|
|
{
|
|
std::vector<dependency_node *> dependents;
|
|
std::vector<dependency_node *> ret;
|
|
+ std::unordered_set<dependency_node *> ret_seen;
|
|
std::set<mod_id> found;
|
|
|
|
// ... (BFS collection into dependents) ...
|
|
@@ -244,8 +249,9 @@
|
|
// BEFORE (CWE-407): std::find on ret vector for dedup, O(N^2)
|
|
for( dependency_node *&dependent : dependents ) {
|
|
- if( std::find( ret.begin(), ret.end(), dependent ) == ret.end() ) {
|
|
+ if( ret_seen.find( dependent ) == ret_seen.end() ) {
|
|
ret.push_back( dependent );
|
|
+ ret_seen.insert( dependent );
|
|
}
|
|
}
|