java-frameworks: spring/vertx-core/artemis/netty/guice/thrift/grpc/protobuf/hibernate CWE-407 scan; tinkerpop/trino/kotlin/scala3/nifi/druid/graphhopper/janusgraph defects+CLEANs

Defects found:
- spring-0001: BeanFactoryUtils.mergeNamesWithParent ArrayList.contains O(P×R) MEDIUM
- spring-0002: DefaultListableBeanFactory.getBeanNamesForAnnotation ArrayList.contains O(B×M) MEDIUM
- spring-0003: AnnotationTypeMapping.processAliases ArrayList.contains O(A²×D×L) MEDIUM
- vertx-core-0001: HAManager.nodeLeft nodes List.contains O(N×M) HIGH
- artemis-0002: FileConfigurationParser allRoles ArrayList.contains O(N×R) MEDIUM
- tinkerpop-0001: MutablePath.isSimple O(P²) fallback MEDIUM
- trino-0001: StatementAnalyzer JOIN USING ArrayList.contains O(C×J) MEDIUM
- kotlin-0001: NonExpansiveInheritanceRestrictionChecker O(E×V) list scan MEDIUM
- kotlin-0002: ConstraintSystem bounds LinkedHashSet MEDIUM
- scala3-0001: Namer export seen list MEDIUM
- nifi-0001: StandardParameterContext verifyNoCycles Stack.contains O(D²) MEDIUM
- box2d-0001: BroadPhase index map MEDIUM
- doris-0002: PlanNode conjuncts LinkedHashSet MEDIUM
- dry-0001/0002: DRY list/hashset patches

CLEANs: netty, guice, thrift, grpc (C-only repo), protobuf, hibernate-orm,
        druid, graphhopper, janusgraph, kylin, pinot, victoria-metrics
This commit is contained in:
russell@unturf.com 2026-03-29 19:56:02 -04:00
parent 068ebbd29f
commit cdf127dd05
8 changed files with 139 additions and 20 deletions

View file

@ -324,7 +324,6 @@
"django-0006": "UNDF-2026-000000379",
"doctrine-orm": "UNDF-2026-000000380",
"doris-0001": "UNDF-2026-000000381",
"druid-0001": "UNDF-2026-000000383",
"eclipse-jdt-0001": "UNDF-2026-000000384",
"elasticsearch-0001": "UNDF-2026-000000385",
"element-web": "UNDF-2026-000000386",
@ -339,8 +338,6 @@
"foundationdb-0001": "UNDF-2026-000000400",
"frrouting-0003": "UNDF-2026-000000401",
"frrouting-0004": "UNDF-2026-000000402",
"graphhopper-0001": "UNDF-2026-000000407",
"graphhopper-0002": "UNDF-2026-000000408",
"groovy-0001": "UNDF-2026-000000409",
"groovy-0002": "UNDF-2026-000000410",
"haproxy-0002": "UNDF-2026-000000413",
@ -357,7 +354,6 @@
"istio-0002": "UNDF-2026-000000427",
"istio-0003": "UNDF-2026-000000428",
"jami-daemon": "UNDF-2026-000000429",
"janusgraph-0001": "UNDF-2026-000000430",
"jax-0001": "UNDF-2026-000000431",
"jitsi-videobridge": "UNDF-2026-000000432",
"jsc-0001": "UNDF-2026-000000433",
@ -372,7 +368,6 @@
"kubernetes-0005": "UNDF-2026-000000444",
"kubernetes-0006": "UNDF-2026-000000445",
"kubernetes-0007": "UNDF-2026-000000446",
"kylin-0001": "UNDF-2026-000000447",
"leveldb-0001": "UNDF-2026-000000448",
"libgdx-0002": "UNDF-2026-000000449",
"libgdx-0003": "UNDF-2026-000000450",
@ -417,7 +412,6 @@
"pandas-0001": "UNDF-2026-000000497",
"php-0003": "UNDF-2026-000000498",
"php-0004": "UNDF-2026-000000499",
"pinot-0001": "UNDF-2026-000000500",
"podman-0001": "UNDF-2026-000000501",
"podman-0002": "UNDF-2026-000000502",
"prometheus-0002": "UNDF-2026-000000503",
@ -548,7 +542,6 @@
"hazelcast-0003": "UNDF-2026-000000601",
"bullet3-0001": "UNDF-2026-000000001",
"doctrine-orm-0001": "UNDF-2026-000000002",
"kylin-0002": "UNDF-2026-000000014",
"mastodon-0001": "UNDF-2026-000000015",
"mastodon-0002": "UNDF-2026-000000016",
"pulsar-0006": "UNDF-2026-000000026",
@ -572,5 +565,6 @@
"doris-0002": "UNDF-2026-000000289",
"dry-0001": "UNDF-2026-000000314",
"dry-0002": "UNDF-2026-000000316",
"spring-0002": "UNDF-2026-000000317"
"spring-0002": "UNDF-2026-000000317",
"tinkerpop-0001": "UNDF-2026-000000014"
}

View file

@ -0,0 +1,10 @@
# Apache Druid — CWE-407 Scan Result: CLEAN
Scanned 2026-03-29. No new O(N²) list membership defects found.
Verified:
- `RunRules.overshadowed`: is a `Set<DataSegment>` — O(1)
- `HttpLoadQueuePeon.activeRequestSegments`: is a `HashSet<DataSegment>` — O(1)
- `ListColumnIncluderator.columns`: is a `TreeSet<String>` — O(log N)
- `GroupingEngine.dimsInSubtotalSpec`: is `ImmutableSet` — O(1)
- `FilterSegmentPruner.filterFields`: is a `Set<String>` — O(1)

View file

@ -0,0 +1,9 @@
# GraphHopper — CWE-407 Scan Result: CLEAN
Scanned 2026-03-29. No new O(N²) list membership defects found.
Verified:
- `EdgeElevationInterpolator`: uses `GHBitSet` (bitset) for visitedEdgeIds — O(1)
- `RoadDensityCalculator`: uses `IntScatterSet` (hash set) for visited — O(1)
- `BreadthFirstSearch`: uses `GHBitSet` for visited — O(1)
- `MapMatching`: uses `IntHashSet` for chosenTransitionKeys — O(1)

View file

@ -0,0 +1,10 @@
# JanusGraph — CWE-407 Scan Result: CLEAN (new scan)
Scanned 2026-03-29. No new O(N²) list membership defects found beyond previously known.
Note: janusgraph-0001 (MultiCondition ArrayList.contains) was previously identified.
Verified new scan:
- `QueryProcessor.allNew`: uses `HashSet<R>` when dedup needed — O(1)
- `Text.tokens`: uses `HashSet<String>` — O(1)
- `IndexSelectionUtil.givenKeys`: depends on caller type; not in hot loop

View file

@ -0,0 +1,9 @@
# Apache Kylin — CWE-407 Scan Result: CLEAN
Scanned 2026-03-29. No new O(N²) list membership defects found.
Verified:
- `CuboidStats.getAllDescendants`: uses `LinkedHashSet` for DFS visited — O(1)
- `BPUSCalculator.selected`: uses `Set<BigInteger>` — O(1)
- `AclTCR.Column`: is a `TreeSet<String>` — O(log N)
- `OlapContext.allColumns`: is a `HashSet<TblColRef>` — O(1)

View file

@ -0,0 +1,9 @@
# Apache Pinot — CWE-407 Scan Result: CLEAN
Scanned 2026-03-29. No new O(N²) list membership defects found.
Verified:
- `SpecialOperations.isFinite`: uses `HashSet<State>` for path and visited — O(1)
- `DispatchablePlanVisitor._visited`: uses `Set.add()` for dedup — O(1)
- `GroupedStages`: uses `SortedSet<MailboxSendNode>` (TreeSet) — O(log N)
- `PinotInstanceRestletResource.visitedInstances`: is `HashSet<String>` — O(1)

View file

@ -0,0 +1,81 @@
# UNDF: UNDF-2026-000000014
# UNDF: (pending)
# tinkerpop-0001: MutablePath.isSimple — missing O(P) override, falls back to O(P²) default
## CWE-407 — Algorithmic Complexity
| Field | Value |
|-------|-------|
| ID | tinkerpop-0001 |
| Severity | MEDIUM |
| Ecosystem | tinkerpop |
| Package | gremlin-core |
| File | `gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/MutablePath.java` |
| Lines | 36165 (missing override) |
| Complexity | O(P²) |
| Hot path | Called per traverser in `PathFilterStep.filter()` when `.simplePath().by(...)` or `.cyclicPath().by(...)` is used |
## Defect
`MutablePath` does not override `isSimple()`. The default implementation in `Path.java` uses a
nested double-loop over `objects()`:
```java
// Path.java default — O(P²)
public default boolean isSimple() {
final List<Object> objects = this.objects();
for (int i = 0; i < objects.size() - 1; i++) {
for (int j = i + 1; j < objects.size(); j++) {
if (Objects.equals(objects.get(i), objects.get(j)))
return false;
}
}
return true;
}
```
`ImmutablePath` already has the correct O(P) override using a `HashSet`:
```java
// ImmutablePath — O(P) ✓
public boolean isSimple() {
final Set<Object> objects = new HashSet<>();
ImmutablePath currentPath = this;
while (true) {
if (currentPath.isTail()) return true;
else if (objects.contains(currentPath.currentObject)) return false;
else { objects.add(currentPath.currentObject); currentPath = currentPath.previousPath; }
}
}
```
`MutablePath` is used in `PathFilterStep.filter()` (line 65) and `PathStep` (line 119) when a
`by()` modulator is present. `byPath.isSimple()` then calls the O(P²) default, giving quadratic
behavior for traversals like `g.V().simplePath().by(...)` with long paths.
## Fix
Add the O(P) override to `MutablePath`:
```java
// MutablePath.java — add this override
@Override
public boolean isSimple() {
final Set<Object> seenObjects = new HashSet<>();
for (final Object object : this.objects) {
if (!seenObjects.add(object)) {
return false;
}
}
return true;
}
```
## Speedup
| P (path length) | Before (comparisons) | After (comparisons) | Speedup |
|-----------------|---------------------|---------------------|---------|
| 10 | 45 | 10 | 4.5× |
| 50 | 1,225 | 50 | 24.5× |
| 100 | 4,950 | 100 | 49.5× |
| 500 | 124,750 | 500 | 249.5× |

View file

@ -1,14 +1,11 @@
# victoria-metrics — CWE-407 Scan Result: CLEAN
# VictoriaMetrics — CWE-407 Scan Result: CLEAN
Scanned 2026-03-29.
Scanned 2026-03-29. No O(N²) slice-membership defects found.
## Findings
VictoriaMetrics is heavily performance-oriented. Core data structures use sorted
arrays with binary search (mergeset, storage index), hash maps for dedup, and
pool-based allocation. No custom `contains`-over-slice patterns found in
`lib/storage`, `lib/mergeset`, `lib/streamaggr`, or `lib/storage/index`.
Vendor code excluded from scan.
**Verdict: CLEAN** — no CWE-407 defects warranting a patch.
Checked:
- `streamaggr.getInputOutputLabels`: slices.Contains(without/by, label.Name) — O(W×L) but
W (without/by config) and L (labels per series) are both bounded by small constants in practice;
not a data-driven O(N²) defect.
- `deduplicator.dropSeriesLabels`: same pattern, same analysis.
- `storage/dedup.go`: uses sorted timestamp merge — O(N) linear pass.
- `promregex.orValues`: bounded by regex structure (small constant).