27 lines
1.6 KiB
Diff
27 lines
1.6 KiB
Diff
# UNDF: UNDF-2026-000000024
|
|
--- a/src/java/org/apache/cassandra/cql3/terms/Lists.java
|
|
+++ b/src/java/org/apache/cassandra/cql3/terms/Lists.java
|
|
@@ -519,15 +519,15 @@ public abstract class Lists
|
|
|
|
- // Note: below, we will call 'contains' on this toDiscard list for each element of existingList.
|
|
- // Meaning that if toDiscard is big, converting it to a HashSet might be more efficient. However,
|
|
- // the read-before-write this operation requires limits its usefulness on big lists, so in practice
|
|
- // toDiscard will be small and keeping a list will be more efficient.
|
|
- List<ByteBuffer> toDiscard = value.getElements();
|
|
- for (Cell<?> cell : complexData)
|
|
- {
|
|
- if (toDiscard.contains(cell.buffer()))
|
|
- params.addTombstone(column, cell.path());
|
|
- }
|
|
+ // CWE-407 fix: convert toDiscard to HashSet before the loop.
|
|
+ // toDiscard.contains() on a List is O(|toDiscard|) per call; with a loop
|
|
+ // over complexData (up to 65535 cells) the total is O(E * D) — quadratic
|
|
+ // when both sides are large. The guardrail threshold (collection_list_size)
|
|
+ // is null by default, so there is no enforced upper bound.
|
|
+ // HashSet.contains() is O(1), making the loop O(E + D) overall.
|
|
+ Set<ByteBuffer> toDiscardSet = new HashSet<>(value.getElements());
|
|
+ for (Cell<?> cell : complexData)
|
|
+ {
|
|
+ if (toDiscardSet.contains(cell.buffer()))
|
|
+ params.addTombstone(column, cell.path());
|
|
+ }
|