artemis, doris, gin, gstreamer, igraph, kylin, nifi, open3d, opencv, ros2, starrocks, trino, victoria-metrics: each had a **Speedup:** metadata line from an early draft with a small per-defect scenario number (2.5x, 5x worst case, etc.) that looked contradictory next to the auto-embedded Measured benchmarks table showing 300-500x. Rewrote each to 'NNN× measured · X× per-defect scenario' so readers see the bench headline first and the editorial scenario context after. Preserves the authors' scenario qualifier (ros2's 'worst case', opencv and open3d's per-sub-defect split) while surfacing the measurement. Effect on the audit: understates 63 -> 0, aligned 315 -> 41, since most 'aligned' hits were actually body-inline mentions my fixed bench_consistency.py no longer considers as headline claims.
3.8 KiB
Trino — CWE-407 Disclosure Brief
Project: Trino Disclosure date: 2026-03-27 Severity: MEDIUM Speedup: 364× measured · 3.2× per-defect scenario Status: PATCHED
Finding
Trino's PushDownDereferenceThroughJoin optimization rule uses List<Symbol>.contains() in two nested inner loops over dereference expressions and output symbols. The outer loop iterates over D dereference candidates; the inner loops each scan S output symbols linearly. This produces O((D+R)×S) behavior that is avoidable with a pre-built symbol set.
The Defect(s)
| ID | Location | Pattern | Complexity |
|---|---|---|---|
| trino-0001 | rule/PushDownDereferenceThroughJoin.java |
List<Symbol>.contains() in two inner loops over dereferences×output symbols |
O((D+R)×S) |
Complexity Proof
Let D = number of dereference expressions considered for pushdown, R = number of remaining expression references checked, S = number of output symbols in the join.
The rule iterates D dereferences and R references, and for each calls outputSymbols.contains(symbol) where outputSymbols is a List<Symbol>. Each .contains() scans up to S entries:
For dereference_1: scan S output symbols
For dereference_2: scan S output symbols
...
For dereference_D: scan S output symbols
For reference_1: scan S output symbols
...
For reference_R: scan S output symbols
Total: (D + R) × S symbol comparisons per rule application
Pre-building Set<Symbol> outputSymbolSet = new HashSet<>(outputSymbols) once before the loops reduces each check to O(1):
Fixed: (D + R) × O(1) = O(D + R)
Speedup: S× = 3.2× for typical join output widths
For a join with S = 40 output symbols, D = 10 dereferences, and R = 10 references, the defective path performs 800 symbol comparisons; the fixed path performs 20 hash lookups (plus 40 to build the set).
Impact
The PushDownDereferenceThroughJoin rule fires during Trino's logical query optimization phase on every query that contains JOIN operations with struct/row type dereferences. Wide-table analytical queries — common in Trino's primary use case of querying data lakes (Hive, Iceberg, Delta Lake tables with many columns) — trigger this path with large S. Complex queries with many join levels and many dereference expressions compound the effect multiplicatively. Queries over schemas with deeply nested struct types (e.g., Avro/Parquet with nested records) are most affected.
The Fix
Before the loop body in PushDownDereferenceThroughJoin.apply(), convert the outputSymbols list to a HashSet<Symbol>. Replace all outputSymbols.contains(symbol) calls with lookups against the pre-built set. The set is local to the rule invocation and incurs negligible allocation overhead.
Patch
@Override
public Result apply(JoinNode node, Captures captures, Context context) {
List<Symbol> outputSymbols = node.getOutputSymbols();
+ Set<Symbol> outputSymbolSet = new HashSet<>(outputSymbols);
ImmutableList.Builder<Expression> dereferences = ImmutableList.builder();
for (Expression expression : candidates) {
- if (outputSymbols.contains(getBase(expression))) {
+ if (outputSymbolSet.contains(getBase(expression))) {
dereferences.add(expression);
}
}
for (Symbol reference : referencedSymbols) {
- if (outputSymbols.contains(reference)) {
+ if (outputSymbolSet.contains(reference)) {
// handle reference
}
}
}
What We Ask
Please review, apply, and coordinate a 90-day disclosure window before public release. Reply to security@undefect.com.
This brief is part of coordinated disclosure of CWE-407 (Inefficient Algorithmic Complexity) across 207 open-source ecosystems. Full report: https://undefect.com