java-topology/defects/jenkins/patch/jenkins-0001-dependency-graph-add-edge-index.patch

59 lines
3 KiB
Diff

# UNDF: UNDF-2026-000000124
diff --git a/core/src/main/java/hudson/model/DependencyGraph.java b/core/src/main/java/hudson/model/DependencyGraph.java
--- a/core/src/main/java/hudson/model/DependencyGraph.java
+++ b/core/src/main/java/hudson/model/DependencyGraph.java
@@ -67,6 +67,7 @@ public class DependencyGraph implements Comparator<AbstractProject> {
private Map<AbstractProject, List<DependencyGroup>> forward = new HashMap<>();
private Map<AbstractProject, List<DependencyGroup>> backward = new HashMap<>();
+ // CWE-407 fix: index for O(1) edge-existence lookup during addDependency
+ private Map<AbstractProject, Map<AbstractProject, DependencyGroup>> forwardIndex = new HashMap<>();
+ private Map<AbstractProject, Map<AbstractProject, DependencyGroup>> backwardIndex = new HashMap<>();
private transient Map<Class<?>, Object> computationalData;
@@ -231,7 +233,8 @@ public class DependencyGraph implements Comparator<AbstractProject> {
public void addDependency(Dependency dep) {
if (built)
throw new IllegalStateException();
- add(forward, dep.getUpstreamProject(), dep);
- add(backward, dep.getDownstreamProject(), dep);
+ add(forward, forwardIndex, dep.getUpstreamProject(), dep);
+ add(backward, backwardIndex, dep.getDownstreamProject(), dep);
}
@@ -318,17 +321,22 @@ public class DependencyGraph implements Comparator<AbstractProject> {
return visited;
}
- private void add(Map<AbstractProject, List<DependencyGroup>> map, AbstractProject key, Dependency dep) {
- List<DependencyGroup> set = map.computeIfAbsent(key, k -> new ArrayList<>());
- for (DependencyGroup d : set) {
- // Check for existing edge that connects the same two projects:
- if (d.getUpstreamProject() == dep.getUpstreamProject() && d.getDownstreamProject() == dep.getDownstreamProject()) {
- d.add(dep);
- return;
- }
- }
- // Otherwise add to list:
- set.add(new DependencyGroup(dep));
+ // CWE-407 fix: was O(degree) linear scan per addDependency; now O(1) via index map.
+ private void add(
+ Map<AbstractProject, List<DependencyGroup>> map,
+ Map<AbstractProject, Map<AbstractProject, DependencyGroup>> index,
+ AbstractProject key, Dependency dep) {
+ List<DependencyGroup> set = map.computeIfAbsent(key, k -> new ArrayList<>());
+ Map<AbstractProject, DependencyGroup> edgeIndex =
+ index.computeIfAbsent(key, k -> new HashMap<>());
+ // O(1) lookup replacing former O(degree) linear scan over DependencyGroup list
+ AbstractProject other = (key == dep.getUpstreamProject())
+ ? dep.getDownstreamProject() : dep.getUpstreamProject();
+ DependencyGroup existing = edgeIndex.get(other);
+ if (existing != null) {
+ existing.add(dep);
+ } else {
+ DependencyGroup dg = new DependencyGroup(dep);
+ set.add(dg);
+ edgeIndex.put(other, dg);
+ }
}