36 lines
1.4 KiB
Diff
36 lines
1.4 KiB
Diff
Fixes pylons-0002: TopologicalSorter.sorted() — `if a in names and b in names` list scan in edge loop O(N*E) — CWE-407.
|
|
|
|
--- a/src/pyramid/util.py
|
|
+++ b/src/pyramid/util.py
|
|
|
|
@@ DEFECT pylons-0002: TopologicalSorter.sorted() lines 506-529
|
|
|
|
def sorted(self):
|
|
order = [(self.first, self.last)]
|
|
- names = [self.first, self.last] # list — O(n) membership below — CWE-407
|
|
+ names_set = {self.first, self.last} # FIX pylons-0002: set for O(1) membership
|
|
graph = {}
|
|
- names.extend(self.names)
|
|
+ names_set.update(self.names)
|
|
|
|
for a, b in self.order:
|
|
order.append((a, b))
|
|
|
|
- for name in names: # still need ordered iteration for add_node
|
|
+ names_ordered = [self.first, self.last]
|
|
+ names_ordered.extend(self.names)
|
|
+ for name in names_ordered:
|
|
add_node(name)
|
|
|
|
has_before, has_after = set(), set()
|
|
for a, b in order: # O(E) loop
|
|
- if a in names and b in names: # O(N) list scan x2 — CWE-407
|
|
+ if a in names_set and b in names_set: # O(1) set lookup x2 — fixed
|
|
add_arc(a, b)
|
|
has_before.add(a)
|
|
has_after.add(b)
|
|
|
|
# SUMMARY:
|
|
# names list replaced by names_set for membership tests.
|
|
# names_ordered list kept for add_node iteration (preserves order; O(N) once).
|
|
# for a,b loop: O(N*E) → O(E) — dominant cost eliminated.
|