java-topology/defects/gcc/patch/gcc-0001-gcov-blocked-map.patch
russell@unturf.com 0a580b313d undefect. CWE-407 — 63 sites patched across 27 ecosystems
Authors: russell@unturf.com · brackishbert@gmail.com · foxhop.net · TimeHexOn.com

Patches, unit tests, benchmarks, whitepaper, and outreach briefs.
Public domain — no copyright claimed. Use freely.
2026-03-26 17:11:57 -04:00

120 lines
4.2 KiB
Diff

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;