java-topology/defects/maven/patch/maven-0004-graph-builder-sorted-projects-index-map.patch

67 lines
3.3 KiB
Diff

# UNDF: UNDF-2026-000000165
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;
+ }
+