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/)
3.3 KiB
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:367–368 |
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:5482mergeExceptions.contains(merge):mergeExceptionsis anArrayList, butaddMergeException()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:2268pendingMerges.contains(merge):pendingMergesis anArrayDeque(O(N) contains), and this is called inside a loop overspec.merges(up to N merges, each checked). This iswaitForMerges()— 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.