undefect. CWE-407 — 92 sites, 42 ecosystems

B&W print-friendly diagrams + tinkerpop-0001 + wave-3 proof sections.
Squash of 94 local commits onto remote master.
This commit is contained in:
russell@unturf.com 2026-03-26 19:48:18 -04:00
parent 0a580b313d
commit db29a08762
1311 changed files with 371202 additions and 1188 deletions

View file

@ -0,0 +1,66 @@
diff --git a/impl/maven-core/src/main/java/org/apache/maven/graph/DefaultGraphBuilder.java b/impl/maven-core/src/main/java/org/apache/maven/graph/DefaultGraphBuilder.java
--- a/impl/maven-core/src/main/java/org/apache/maven/graph/DefaultGraphBuilder.java
+++ b/impl/maven-core/src/main/java/org/apache/maven/graph/DefaultGraphBuilder.java
@@ -56,6 +56,7 @@ import static java.util.Comparator.comparing;
/**
* Builds the {@link ProjectDependencyGraph inter-dependencies graph} between projects in the reactor.
*/
+// CWE-407 fix applied in trimProjectsToRequest, trimSelectedProjects, includeAlsoMakeTransitively:
+// result.sort(comparing(sortedProjects::indexOf)) is O(N log N) on average but each indexOf call
+// is O(N) → total sort is O(N² log N) for large reactors.
+// Fix: build a projectOrderMap once and sort by map lookup (O(1) per comparison → O(N log N)).
@Named(GraphBuilder.HINT)
@Singleton
public class DefaultGraphBuilder implements GraphBuilder {
@@ -152,9 +154,10 @@ private List<MavenProject> trimProjectsToRequest(
List<MavenProject> result = activeProjects;
if (request.getPom() != null) {
result = getProjectsInRequestScope(request, activeProjects);
- List<MavenProject> sortedProjects = graph.getSortedProjects();
- result.sort(comparing(sortedProjects::indexOf));
+ // CWE-407 fix: was O(N² log N); now O(N log N) with index map
+ Map<MavenProject, Integer> orderMap = buildOrderMap(graph.getSortedProjects());
+ result.sort(comparing(orderMap::get));
result = includeAlsoMakeTransitively(result, request, graph);
}
@@ -185,10 +188,10 @@ private List<MavenProject> trimSelectedProjects(
if (!selectedProjects.isEmpty()) {
result = new ArrayList<>(selectedProjects);
result = includeAlsoMakeTransitively(result, request, graph);
- // Order the new list in the original order
- List<MavenProject> sortedProjects = graph.getSortedProjects();
- result.sort(comparing(sortedProjects::indexOf));
+ // CWE-407 fix: O(N² log N) → O(N log N)
+ Map<MavenProject, Integer> orderMap = buildOrderMap(graph.getSortedProjects());
+ result.sort(comparing(orderMap::get));
}
}
@@ -288,9 +291,14 @@ private List<MavenProject> includeAlsoMakeTransitively(
result = new ArrayList<>(projectsSet);
- // Order the new list in the original order
- List<MavenProject> sortedProjects = graph.getSortedProjects();
- result.sort(comparing(sortedProjects::indexOf));
+ // CWE-407 fix: O(N² log N) → O(N log N)
+ Map<MavenProject, Integer> orderMap = buildOrderMap(graph.getSortedProjects());
+ result.sort(comparing(orderMap::get));
}
return result;
}
+ /** Build a project → sort-order index map in O(N) for subsequent O(1) lookups. */
+ private static Map<MavenProject, Integer> buildOrderMap(List<MavenProject> sortedProjects) {
+ Map<MavenProject, Integer> map = new java.util.IdentityHashMap<>(sortedProjects.size() * 2);
+ for (int i = 0; i < sortedProjects.size(); i++) {
+ map.put(sortedProjects.get(i), i);
+ }
+ return map;
+ }
+

View file

@ -0,0 +1,27 @@
diff --git a/impl/maven-core/src/main/java/org/apache/maven/lifecycle/internal/concurrent/BuildPlanLogger.java b/impl/maven-core/src/main/java/org/apache/maven/lifecycle/internal/concurrent/BuildPlanLogger.java
--- a/impl/maven-core/src/main/java/org/apache/maven/lifecycle/internal/concurrent/BuildPlanLogger.java
+++ b/impl/maven-core/src/main/java/org/apache/maven/lifecycle/internal/concurrent/BuildPlanLogger.java
@@ -21,6 +21,8 @@ package org.apache.maven.lifecycle.internal.concurrent;
import java.util.Comparator;
import java.util.HashSet;
+import java.util.IdentityHashMap;
+import java.util.Map;
import java.util.List;
import java.util.Optional;
import java.util.Set;
@@ -74,8 +76,13 @@ public class BuildPlanLogger {
} else {
+ // CWE-407 fix: plan.sortedNodes()::indexOf is O(N) per step → O(N²) total for the
+ // stream sorted() call over N steps. Build an O(1) index map once.
+ List<BuildStep> sorted = plan.sortedNodes();
+ Map<BuildStep, Integer> indexMap = new IdentityHashMap<>(sorted.size() * 2);
+ for (int i = 0; i < sorted.size(); i++) {
+ indexMap.put(sorted.get(i), i);
+ }
plan.steps(project)
.filter(step ->
step.phase != null && step.executions().findAny().isPresent())
- .sorted(Comparator.comparingInt(plan.sortedNodes()::indexOf))
+ .sorted(Comparator.comparingInt(step -> indexMap.getOrDefault(step, Integer.MAX_VALUE)))
.forEach(step -> {