36 lines
1.8 KiB
Diff
36 lines
1.8 KiB
Diff
# UNDF: UNDF-2026-000000119
|
|
diff --git a/src/java.base/share/classes/jdk/internal/module/ModuleHashesBuilder.java b/src/java.base/share/classes/jdk/internal/module/ModuleHashesBuilder.java
|
|
index cebca6fb..5514eb20 100644
|
|
--- a/src/java.base/share/classes/jdk/internal/module/ModuleHashesBuilder.java
|
|
+++ b/src/java.base/share/classes/jdk/internal/module/ModuleHashesBuilder.java
|
|
@@ -264,21 +264,26 @@ public void reverse(Consumer<T> action) {
|
|
private void sort() {
|
|
Set<T> visited = new HashSet<>();
|
|
Deque<T> stack = new ArrayDeque<>();
|
|
- graph.nodes.forEach(node -> visit(node, visited, stack));
|
|
+ // CWE-407 fix: parallel Set for O(1) stack membership test.
|
|
+ // Deque.contains() is O(n); stackSet.contains() is O(1).
|
|
+ Set<T> stackSet = new HashSet<>();
|
|
+ graph.nodes.forEach(node -> visit(node, visited, stack, stackSet));
|
|
}
|
|
|
|
private Set<T> children(T node) {
|
|
return graph.edges().get(node);
|
|
}
|
|
|
|
- private void visit(T node, Set<T> visited, Deque<T> stack) {
|
|
+ private void visit(T node, Set<T> visited, Deque<T> stack, Set<T> stackSet) {
|
|
if (visited.add(node)) {
|
|
stack.push(node);
|
|
- children(node).forEach(child -> visit(child, visited, stack));
|
|
+ stackSet.add(node);
|
|
+ children(node).forEach(child -> visit(child, visited, stack, stackSet));
|
|
stack.pop();
|
|
+ stackSet.remove(node);
|
|
result.addLast(node);
|
|
}
|
|
- else if (stack.contains(node)) {
|
|
+ else if (stackSet.contains(node)) {
|
|
throw new IllegalArgumentException(
|
|
"Cycle detected: " + node + " -> " + children(node));
|
|
}
|