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:
parent
a4b0cf4edd
commit
3eebda37e1
38 changed files with 3651 additions and 0 deletions
|
|
@ -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.
|
||||
|
|
@ -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).
|
||||
Loading…
Add table
Add a link
Reference in a new issue