no-stone-unturned wave: 8 new defects, 15 CLEAN confirmations; count 621→629

New defects (all PASS):
- exim-0001: same_hosts() MX-segment O(H²) → AVL set O(H log H), 10.5x at H=20
- minecraft-0001: DependencySorter.isCyclic no visited set O(E^D) → O(E), 342,000x at D=24
- minecraft-0002: PistonStructureResolver toPush ArrayList O(N²) → HashSet O(N)
- minecraft-0003: RedstoneWireEvaluator Deque.contains O(N²) → HashSet O(N)
- minecraft-0004: MoveThroughVillageGoal visited List O(N²) → HashSet O(N)
- mpich-0001: group_lpid_to_rank O(N²) → HashMap O(N), 313x at N=1000
- ompi-0001: group_overlap process-name scan O(N×M) → HashMap O(N+M), 2048x
- pcl-0001: RegionGrowing::getSegmentFromPoint O(C×S) → point_labels[] O(1), 50000x

CLEAN confirmed: esbuild, express, koa, ktor, lucene, mpich-recvq, ompi-startup,
  prosody, roda, rust/rustc-wave2, signal-server, solana, wiredtiger, wireguard-tools,
  linux-kernel (pointer to linux/)
This commit is contained in:
russell@unturf.com 2026-03-29 16:11:50 -04:00
parent dd72c2ba0d
commit a629bd0bbf
46 changed files with 2687 additions and 128 deletions

View file

@ -0,0 +1,50 @@
# Lucene CWE-407 Scan — CLEAN
**Date:** 2026-03-29
**Target:** Apache Lucene (`~/git/lucene/`)
**Language:** Java
**Version:** main branch (depth-1 clone)
## Scan Scope
| Area | Files Checked |
|------|--------------|
| `lucene/core/src/java/org/apache/lucene/index/` | IndexWriter, TieredMergePolicy, LogMergePolicy, TemporalMergePolicy, SegmentInfos, ReaderPool, DocumentsWriterPerThreadPool, BufferedUpdatesStream, UpgradeIndexMergePolicy, ConcurrentMergeScheduler, PerFieldMergeState |
| `lucene/core/src/java/org/apache/lucene/search/` | BooleanQuery |
| `lucene/core/src/java/org/apache/lucene/util/hnsw/` | UpdateGraphsUtils |
| `lucene/core/src/java/org/apache/lucene/codecs/perfield/` | PerFieldMergeState |
## Methodology
Searched for `List.contains()`, `ArrayList.contains()`, `Collection.contains()`, and `.indexOf()` calls nested inside loops over segment lists or merge candidates. Cross-referenced the declared type of each collection receiving a `.contains()` call.
## Findings
All `.contains()` calls in hot paths use hash-backed collections:
| Location | Collection | Type | Verdict |
|----------|-----------|------|---------|
| `TieredMergePolicy.java:316,765,938` | `merging` | `Set<SegmentCommitInfo>` (from `getMergingSegments()`) | O(1) |
| `LogMergePolicy.java:497` | `mergingSegments` | `Set<SegmentCommitInfo>` | O(1) |
| `TemporalMergePolicy.java` | `merging` | `Set<SegmentCommitInfo>` | O(1) |
| `IndexWriter.java:2268` | `pendingMerges` | `ArrayDeque<OneMerge>` — but call is not in inner loop, just poll loop once | O(D) one-shot |
| `IndexWriter.java:2268` | `runningMerges` | `HashSet<OneMerge>` | O(1) |
| `IndexWriter.java:3862` | `mergedSegmentNames` | `HashSet<String>` (constructed on line 3862) | O(1) |
| `IndexWriter.java:6445` | `alreadySeenSegments` | `Set<SegmentCommitInfo>` (parameter type) | O(1) |
| `IndexWriter.java:5482` | `mergeExceptions` | `ArrayList<OneMerge>` — called once in `addMergeException()`, not in a segment loop | O(E) isolated |
| `BooleanQuery.java:404,412` | `intersection` | `HashSet<Query>` | O(1) |
| `BooleanQuery.java:367368` | clause sets | `Collection<Query>` backed by map values (List per Occur) | rewrite-time, bounded clauses |
| `PerFieldMergeState.java:105,108` | `filteredNames` | `HashSet<String>` | O(1) |
| `UpdateGraphsUtils.java:45,74` | `j` | `IntHashSet` | O(1) |
## Notable Non-Defects
- **`IndexWriter.java:5482` `mergeExceptions.contains(merge)`**: `mergeExceptions` is an `ArrayList`, but `addMergeException()` is only called when a merge throws an exception (error path, infrequent). It is not called inside a per-segment loop. Not a hot path.
- **`IndexWriter.java:2268` `pendingMerges.contains(merge)`**: `pendingMerges` is an `ArrayDeque` (O(N) contains), and this is called inside a loop over `spec.merges` (up to N merges, each checked). This is `waitForMerges()` — only called when the caller explicitly waits for forced merges to complete. Not a per-document or per-query hot path. Excluded.
## Result
**CLEAN** — no CWE-407 defects confirmed in Lucene core.
The codebase consistently uses `Set<>` or `HashSet<>` for merge-state membership checks in the hot segment-iteration paths. The design is intentionally correct: `getMergingSegments()` returns a `Set<SegmentCommitInfo>` specifically so that callers can do O(1) membership checks in their segment-iteration loops.