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.
35 lines
1,017 B
Diff
35 lines
1,017 B
Diff
diff --git a/scripts/headerdep.pl b/scripts/headerdep.pl
|
|
index ebfcbef..17d7d44 100755
|
|
--- a/scripts/headerdep.pl
|
|
+++ b/scripts/headerdep.pl
|
|
@@ -139,10 +139,12 @@ sub print_cycle {
|
|
}
|
|
|
|
# Find and print the smallest cycle starting in the specified node.
|
|
+# CWE-407 fix: carry a parallel hash alongside each path so cycle
|
|
+# membership checks are O(1) via exists{} instead of O(depth) via grep{}.
|
|
sub detect_cycles {
|
|
- my @queue = map { [[0, $_]] } @_;
|
|
+ my @queue = map { [[[0, $_]], {$_ => 1}] } @_;
|
|
while(@queue) {
|
|
- my $top = pop @queue;
|
|
+ my ($top, $top_set) = @{pop @queue};
|
|
my $name = $top->[-1]->[1];
|
|
|
|
for my $dep (@{$deps{$name}}) {
|
|
@@ -150,13 +152,13 @@ sub detect_cycles {
|
|
|
|
# If the dep already exists in the chain, we have a
|
|
# cycle...
|
|
- if(grep { $_->[1] eq $dep->[1] } @$top) {
|
|
+ if(exists $top_set->{$dep->[1]}) {
|
|
print_cycle($chain);
|
|
next if $opt_all;
|
|
return;
|
|
}
|
|
|
|
- push @queue, $chain;
|
|
+ push @queue, [$chain, {%$top_set, $dep->[1] => 1}];
|
|
}
|
|
}
|
|
}
|