java-topology/defects/helm/unit/HelmTest.java
russell@unturf.com 9934133dcf whitepaper: 312 sites / 151 ecosystems — wave2+3 defect tables and PDF rebuild
Add 88 new defect entries to HIGH and MEDIUM tables:
  HIGH: mysql-0001/0002, mariadb-0001, redis-0001/0002, valkey-0001/0002, openvpn-0001,
        vlc-0001, prometheus-0001, otel-collector-0001, cockroachdb-0001..0004,
        tidb-0001..0008, kubernetes-0001/0002, go-0001, kotlin-0002, scala-0001,
        allegro5-0001, sdl2-0001, grafana-0001, clickhouse-0001, duckdb-0001,
        mongodb-0001, envoy-0001, istio-0001, cilium-0001, linkerd2-0001,
        linux-0001/0002/0003, tor-0002/0003, curl-0001, julia-0001, lua-0001,
        perl5-0001, nats-0001, spring-0003/0004, tomcat-0001, onos-0002, odl-0002

  MEDIUM: helm-0001, mariadb-0002, openssl-0001/0002, memcached-0001,
          cassandra-0001..0004, flink-0001, storm-0001/0002, zookeeper-0001..0003,
          pip-0001, gradle-0001, nginx-0001, haproxy-0001, caddy-0001, varnish-0001,
          ffmpeg-0001, gstreamer-0001, raylib-0001, love2d-0001, php-0001/0002,
          r-source-0001, cpython-0002, ruby-0001, rabbitmq-0003/0004, activemq-0001,
          ovs-0001, onos-0003, odl-0002, jetty-0001

PDF: 976K
2026-03-27 15:23:43 -04:00

120 lines
3.9 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package unit;
import java.util.*;
/**
* Standalone unit test for helm CWE-407 defect.
*
* helm-0001: processDependencyEnabled — O(n²) nested dependency lookup
* Pattern A: for each existing dep, scan all metadata deps — O(E × M).
* Pattern B: getAliasDependency called per metadata dep — O(M × C).
*
* slow() counts ops for both patterns with nested loops.
* fast() counts ops using a pre-built name→entry map for O(1) lookups.
* Assert: slowOps > fastOps * 5x for D=200 dependencies.
*/
public class HelmTest {
static class ChartDep {
String name;
String version;
ChartDep(String name, String version) { this.name = name; this.version = version; }
}
/**
* Slow path — Pattern A: O(existing × metaDeps).
* Pattern B: O(metaDeps × charts) where getAliasDependency scans charts linearly.
*/
static long slowProcessDependencies(List<ChartDep> existing, List<ChartDep> metaDeps) {
long ops = 0;
// Pattern A: filter existing not in metaDeps
List<ChartDep> chartDeps = new ArrayList<>();
outer:
for (ChartDep ex : existing) {
for (ChartDep req : metaDeps) { // O(M) per existing item
ops++;
if (ex.name.equals(req.name)) {
continue outer;
}
}
chartDeps.add(ex);
}
// Pattern B: for each metaDep, scan existing (getAliasDependency linear scan)
for (ChartDep req : metaDeps) {
for (ChartDep ch : existing) { // O(C) per metaDep
ops++;
if (ch.name.equals(req.name)) {
chartDeps.add(ch); // alias copy
break;
}
}
}
return ops;
}
/**
* Fast path — build name→ChartDep maps once; O(1) lookups.
*/
static long fastProcessDependencies(List<ChartDep> existing, List<ChartDep> metaDeps) {
long ops = 0;
// Build index: O(E) + O(M)
Map<String, ChartDep> metaByName = new HashMap<>(metaDeps.size());
for (ChartDep req : metaDeps) {
ops++;
metaByName.put(req.name, req);
}
Map<String, ChartDep> chartsByName = new HashMap<>(existing.size());
for (ChartDep ch : existing) {
ops++;
chartsByName.put(ch.name, ch);
}
// Pattern A replacement — O(E) with O(1) lookup
List<ChartDep> chartDeps = new ArrayList<>();
for (ChartDep ex : existing) {
ops++;
if (!metaByName.containsKey(ex.name)) {
chartDeps.add(ex);
}
}
// Pattern B replacement — O(M) with O(1) lookup
for (ChartDep req : metaDeps) {
ops++;
ChartDep ch = chartsByName.get(req.name);
if (ch != null) {
chartDeps.add(ch);
}
}
return ops;
}
static void testProcessDependencies() {
int D = 200; // number of dependencies
List<ChartDep> existing = new ArrayList<>(D);
List<ChartDep> metaDeps = new ArrayList<>(D);
for (int i = 0; i < D; i++) {
existing.add(new ChartDep("chart-" + i, "1.0." + i));
metaDeps.add(new ChartDep("chart-" + i, ">=1.0.0"));
}
long sOps = slowProcessDependencies(existing, metaDeps);
long fOps = fastProcessDependencies(existing, metaDeps);
int Nx = 5;
boolean pass = sOps > fOps * Nx;
System.out.printf("helm-0001 [D=%d]: slow=%d fast=%d ratio=%.1fx — %s%n",
D, sOps, fOps, (double) sOps / fOps, pass ? "PASS" : "FAIL");
if (!pass) throw new AssertionError("helm-0001 FAIL: slow=" + sOps + " fast=" + fOps);
}
public static void main(String[] args) {
testProcessDependencies();
System.out.println("1/1 PASS");
}
}