java-topology/defects/cataclysm-0002/patch/cataclysm-0002.patch
russell@unturf.com 8ea8ad434f undf: assign 935-937; cataclysm-dda 3 CWE-407 defects
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
2026-03-31 10:08:23 -04:00

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 );
}
}