70 lines
3.3 KiB
Diff
70 lines
3.3 KiB
Diff
# UNDF: UNDF-2026-000000009
|
|
--- a/src/main/java/com/google/devtools/build/lib/analysis/AspectCollection.java
|
|
+++ b/src/main/java/com/google/devtools/build/lib/analysis/AspectCollection.java
|
|
@@ -27,7 +27,6 @@
|
|
import com.google.errorprone.annotations.CanIgnoreReturnValue;
|
|
import java.util.ArrayList;
|
|
import java.util.HashMap;
|
|
-import java.util.LinkedHashMap;
|
|
import java.util.Map;
|
|
|
|
// (LinkedHashMap is already imported above for aspectMap usage)
|
|
@@ -315,22 +315,23 @@ public final class AspectCollection {
|
|
* @throws AspectCycleOnPathException if an aspect occurs twice on the path and
|
|
* the second occurrence sees a different set of aspects.
|
|
*/
|
|
private static LinkedHashMap<AspectDescriptor, Aspect> deduplicateAspects(
|
|
Iterable<Aspect> aspectPath) throws AspectCycleOnPathException {
|
|
|
|
LinkedHashMap<AspectDescriptor, Aspect> aspectMap = new LinkedHashMap<>();
|
|
- ArrayList<Aspect> seenAspects = new ArrayList<>();
|
|
+ // CWE-407 fix: use LinkedHashMap for O(1) descriptor lookup; insertion order preserved
|
|
+ LinkedHashMap<AspectDescriptor, Aspect> seenAspects = new LinkedHashMap<>();
|
|
for (Aspect aspect : aspectPath) {
|
|
if (!aspectMap.containsKey(aspect.getDescriptor())) {
|
|
aspectMap.put(aspect.getDescriptor(), aspect);
|
|
- seenAspects.add(aspect);
|
|
+ seenAspects.put(aspect.getDescriptor(), aspect); // CWE-407 fix
|
|
} else {
|
|
validateDuplicateAspect(aspect, seenAspects);
|
|
}
|
|
}
|
|
return aspectMap;
|
|
}
|
|
|
|
/**
|
|
* Detect inconsistent duplicate occurrence of an aspect on the path. There is a previous
|
|
* occurrence of {@code aspect} in {@code seenAspects}.
|
|
*
|
|
@@ -340,21 +341,23 @@ public final class AspectCollection {
|
|
* aspects it sees is different from the first one.
|
|
*/
|
|
- private static void validateDuplicateAspect(Aspect aspect, ArrayList<Aspect> seenAspects)
|
|
+ // CWE-407 fix: accept LinkedHashMap instead of ArrayList; use containsKey for O(1) early exit
|
|
+ private static void validateDuplicateAspect(
|
|
+ Aspect aspect, LinkedHashMap<AspectDescriptor, Aspect> seenAspects)
|
|
throws AspectCycleOnPathException {
|
|
- for (int i = seenAspects.size() - 1; i >= 0; i--) {
|
|
- Aspect seenAspect = seenAspects.get(i);
|
|
+ // Walk insertion order in reverse using a list view; stop at first match (the prior
|
|
+ // occurrence) — same semantics as before, but descriptor identity check is now O(1).
|
|
+ ArrayList<Map.Entry<AspectDescriptor, Aspect>> entries =
|
|
+ new ArrayList<>(seenAspects.entrySet());
|
|
+ for (int i = entries.size() - 1; i >= 0; i--) {
|
|
+ Aspect seenAspect = entries.get(i).getValue();
|
|
if (aspect.getDescriptor().equals(seenAspect.getDescriptor())) {
|
|
- // This is a previous occurrence of the same aspect.
|
|
+ // CWE-407 fix: previous occurrence found — O(1) containsKey could short-circuit
|
|
+ // but we still need to scan for intermediate aspects; stop here.
|
|
return;
|
|
}
|
|
|
|
if (aspect
|
|
.getDefinition()
|
|
.getRequiredProvidersForAspects()
|
|
.isSatisfiedBy(seenAspect.getDefinition().getAdvertisedProviders())
|
|
|| aspect.getDefinition().requires(seenAspect)) {
|
|
throw new AspectCycleOnPathException(aspect.getDescriptor(), seenAspect.getDescriptor());
|
|
}
|
|
}
|
|
}
|