121 lines
4.2 KiB
Diff
121 lines
4.2 KiB
Diff
# UNDF: UNDF-2026-000000076
|
|
diff --git a/gcc/gcov.cc b/gcc/gcov.cc
|
|
index 6256caa..5965e16 100644
|
|
--- a/gcc/gcov.cc
|
|
+++ b/gcc/gcov.cc
|
|
@@ -50,6 +50,7 @@ along with Gcov; see the file COPYING3. If not see
|
|
#include "xregex.h"
|
|
#include "graphds.h"
|
|
|
|
+#include <unordered_map>
|
|
#include <zlib.h>
|
|
#include <getopt.h>
|
|
|
|
@@ -886,6 +887,10 @@ find_arc (const block_info &block, unsigned dest)
|
|
|
|
typedef vector<arc_info *> arc_vector_t;
|
|
typedef vector<const block_info *> block_vector_t;
|
|
+/* CWE-407 fix: map each blocked block to its block-list.
|
|
+ Replaces parallel (blocked, block_lists) vectors; gives O(1) membership
|
|
+ test (was O(n) find) and O(1) lookup for the associated block-list. */
|
|
+typedef unordered_map<const block_info *, block_vector_t> blocked_map_t;
|
|
|
|
/* Handle cycle identified by EDGES, where the function finds minimum cs_count
|
|
and subtract the value from all counts. The subtracted value is added
|
|
@@ -914,23 +919,17 @@ handle_cycle (const arc_vector_t &edges, int64_t &count)
|
|
blocked by U in BLOCK_LISTS. */
|
|
|
|
static void
|
|
-unblock (const block_info *u, block_vector_t &blocked,
|
|
- vector<block_vector_t > &block_lists)
|
|
+unblock (const block_info *u, blocked_map_t &blocked_map)
|
|
{
|
|
- block_vector_t::iterator it = find (blocked.begin (), blocked.end (), u);
|
|
- if (it == blocked.end ())
|
|
+ auto it = blocked_map.find (u);
|
|
+ if (it == blocked_map.end ())
|
|
return;
|
|
|
|
- unsigned index = it - blocked.begin ();
|
|
- blocked.erase (it);
|
|
+ block_vector_t to_unblock = std::move (it->second);
|
|
+ blocked_map.erase (it);
|
|
|
|
- block_vector_t to_unblock (block_lists[index]);
|
|
-
|
|
- block_lists.erase (block_lists.begin () + index);
|
|
-
|
|
- for (block_vector_t::iterator it = to_unblock.begin ();
|
|
- it != to_unblock.end (); it++)
|
|
- unblock (*it, blocked, block_lists);
|
|
+ for (const block_info *b : to_unblock)
|
|
+ unblock (b, blocked_map);
|
|
}
|
|
|
|
/* Return true when PATH contains a zero cycle arc count. */
|
|
@@ -951,15 +950,13 @@ path_contains_zero_or_negative_cycle_arc (arc_vector_t &path)
|
|
|
|
static bool
|
|
circuit (block_info *v, arc_vector_t &path, block_info *start,
|
|
- block_vector_t &blocked, vector<block_vector_t> &block_lists,
|
|
- line_info &linfo, int64_t &count)
|
|
+ blocked_map_t &blocked_map, line_info &linfo, int64_t &count)
|
|
{
|
|
bool loop_found = false;
|
|
|
|
- /* Add v to the block list. */
|
|
- gcc_assert (find (blocked.begin (), blocked.end (), v) == blocked.end ());
|
|
- blocked.push_back (v);
|
|
- block_lists.push_back (block_vector_t ());
|
|
+ /* Add v to the blocked map. */
|
|
+ gcc_assert (blocked_map.find (v) == blocked_map.end ());
|
|
+ blocked_map[v] = block_vector_t ();
|
|
|
|
for (arc_info *arc = v->succ; arc; arc = arc->succ_next)
|
|
{
|
|
@@ -977,15 +974,15 @@ circuit (block_info *v, arc_vector_t &path, block_info *start,
|
|
loop_found = true;
|
|
}
|
|
else if (!path_contains_zero_or_negative_cycle_arc (path)
|
|
- && find (blocked.begin (), blocked.end (), w) == blocked.end ())
|
|
- loop_found |= circuit (w, path, start, blocked, block_lists, linfo,
|
|
- count);
|
|
+ /* CWE-407 fix: O(1) map lookup replaces O(n) find scan. */
|
|
+ && blocked_map.find (w) == blocked_map.end ())
|
|
+ loop_found |= circuit (w, path, start, blocked_map, linfo, count);
|
|
|
|
path.pop_back ();
|
|
}
|
|
|
|
if (loop_found)
|
|
- unblock (v, blocked, block_lists);
|
|
+ unblock (v, blocked_map);
|
|
else
|
|
for (arc_info *arc = v->succ; arc; arc = arc->succ_next)
|
|
{
|
|
@@ -995,10 +992,9 @@ circuit (block_info *v, arc_vector_t &path, block_info *start,
|
|
|| !linfo.has_block (w))
|
|
continue;
|
|
|
|
- size_t index
|
|
- = find (blocked.begin (), blocked.end (), w) - blocked.begin ();
|
|
- gcc_assert (index < blocked.size ());
|
|
- block_vector_t &list = block_lists[index];
|
|
+ auto it = blocked_map.find (w);
|
|
+ gcc_assert (it != blocked_map.end ());
|
|
+ block_vector_t &list = it->second;
|
|
if (find (list.begin (), list.end (), v) == list.end ())
|
|
list.push_back (v);
|
|
}
|
|
@@ -1022,9 +1018,8 @@ get_cycles_count (line_info &linfo)
|
|
it != linfo.blocks.end (); it++)
|
|
{
|
|
arc_vector_t path;
|
|
- block_vector_t blocked;
|
|
- vector<block_vector_t > block_lists;
|
|
- circuit (*it, path, *it, blocked, block_lists, linfo, count);
|
|
+ blocked_map_t blocked_map;
|
|
+ circuit (*it, path, *it, blocked_map, linfo, count);
|
|
}
|
|
|
|
return count;
|