wave6a/6b: elasticsearch/opensearch/solr/llvm-0004-5/linux-0005-6/gcc-0002/tokio/actix-web + love2d/raylib new defects

This commit is contained in:
russell@unturf.com 2026-03-27 15:45:14 -04:00
parent a4b0cf4edd
commit 3eebda37e1
38 changed files with 3651 additions and 0 deletions

View file

@ -0,0 +1,55 @@
# opensearch-001: ImmutableCacheStatsHolder O(n²) levelsList.contains in filterLevels
## Classification
- **CWE**: CWE-407 (Inefficient Algorithmic Complexity)
- **Severity**: MEDIUM
- **Path**: Cache stats reporting — called on every stats API request
## Location
`server/src/main/java/org/opensearch/common/cache/stats/ImmutableCacheStatsHolder.java:232-235`
## Defect
```java
private List<String> filterLevels(String[] levels, List<String> dimensionNames) {
if (levels == null) {
return dimensionNames;
}
List<String> levelsList = Arrays.asList(levels); // backed array — O(n) contains
List<String> result = new ArrayList<>();
for (String dimensionName : dimensionNames) {
if (levelsList.contains(dimensionName)) { // O(levels.length) per iteration
result.add(dimensionName);
}
}
return result;
}
```
`Arrays.asList()` returns a fixed-size list backed by the array — `contains()` is a
linear O(levels.length) scan. The outer loop runs `dimensionNames.size()` times.
Total: **O(dimensionNames × levels)** = O(n²) when both grow proportionally.
For a cluster with D dimensions and L requested levels this fires on every
`/_nodes/stats` or cache stats request.
## Fix
```java
Set<String> levelsSet = new HashSet<>(Arrays.asList(levels)); // O(L) build
for (String dimensionName : dimensionNames) {
if (levelsSet.contains(dimensionName)) { // O(1)
result.add(dimensionName);
}
}
```
## Complexity
| Metric | Before | After |
|--------|--------|-------|
| contains() | O(L) | O(1) |
| Full filter | O(D×L) | O(D+L) |
## Affected Versions
All OpenSearch versions with the multi-tier cache stats feature.

View file

@ -0,0 +1,64 @@
# opensearch-002: MustToFilterRewriter O(n²) mustClausesToMove.contains in copy loop
## Classification
- **CWE**: CWE-407 (Inefficient Algorithmic Complexity)
- **Severity**: MEDIUM
- **Path**: Query rewrite phase — fires on every bool query with must clauses
## Location
`server/src/main/java/org/opensearch/search/query/rewriters/MustToFilterRewriter.java:104`
## Defect
```java
List<QueryBuilder> mustClausesToMove = new ArrayList<>();
// Phase 1: identify clauses to move (O(n))
for (QueryBuilder clause : boolQuery.must()) {
QueryBuilder rewrittenClause = rewriteIfNeeded(clause, context);
rewrittenMustClauses.add(rewrittenClause);
if (isClauseIrrelevantToScoring(rewrittenClause, context)) {
mustClausesToMove.add(rewrittenClause);
}
}
// Phase 2: copy must clauses except moved ones (O(n) × O(n) = O(n²))
for (QueryBuilder rewrittenClause : rewrittenMustClauses) {
if (!mustClausesToMove.contains(rewrittenClause)) { // O(mustClausesToMove.size())
rewritten.must(rewrittenClause);
}
}
```
`mustClausesToMove` is an `ArrayList`. The copy loop iterates all `rewrittenMustClauses`
(up to M items) and for each calls `mustClausesToMove.contains()` which is O(K) where K
is the number of clauses to move.
Total: **O(M × K)** — worst case O(n²) when half the clauses are moved.
This fires on every search request that includes a bool query with must clauses, which is
the majority of structured OpenSearch queries.
## Fix
```java
Set<QueryBuilder> mustClausesToMoveSet = new HashSet<>(mustClausesToMove);
// ...
for (QueryBuilder rewrittenClause : rewrittenMustClauses) {
if (!mustClausesToMoveSet.contains(rewrittenClause)) { // O(1) identity hash
rewritten.must(rewrittenClause);
}
}
```
Note: `QueryBuilder` identity equality via `HashSet` is appropriate here since
`rewrittenMustClauses` contains the same object references added to `mustClausesToMove`.
## Complexity
| Metric | Before | After |
|--------|--------|-------|
| contains() | O(K) | O(1) |
| Full copy phase | O(M×K) | O(M+K) |
## Affected Versions
All OpenSearch versions with the MustToFilterRewriter (added in query rewriter framework).