whitepaper: 366/178 — wave5 defect tables + PDF rebuild
This commit is contained in:
parent
835ae73b0f
commit
a4b0cf4edd
79 changed files with 3829 additions and 17 deletions
222
defects/podman/unit/CapDiffAlgorithm.java
Normal file
222
defects/podman/unit/CapDiffAlgorithm.java
Normal file
|
|
@ -0,0 +1,222 @@
|
|||
package unit;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* CWE-407 unit test: podman determineCapAddDropFromCapabilities
|
||||
* File: libpod/kube.go:1280 — determineCapAddDropFromCapabilities
|
||||
*
|
||||
* Slow: for each cap, calls slices.Contains on opposing slice → O(n²)
|
||||
* Fast: build maps for both slices first → O(n)
|
||||
*
|
||||
* Run: javac -d . CapDiffAlgorithm.java && java -ea unit.CapDiffAlgorithm
|
||||
*/
|
||||
public class CapDiffAlgorithm {
|
||||
|
||||
// ── Slow implementation ───────────────────────────────────────────────────
|
||||
static class SlowCapDiff {
|
||||
final long ops;
|
||||
final List<String> drop;
|
||||
final List<String> add;
|
||||
|
||||
SlowCapDiff(List<String> defaultCaps, List<String> containerCaps) {
|
||||
long count = 0;
|
||||
Map<String, Boolean> dedupDrop = new HashMap<>();
|
||||
Map<String, Boolean> dedupAdd = new HashMap<>();
|
||||
List<String> dropList = new ArrayList<>();
|
||||
List<String> addList = new ArrayList<>();
|
||||
|
||||
// Find dropped: in defaultCaps but not containerCaps
|
||||
for (String cap : defaultCaps) {
|
||||
boolean found = false;
|
||||
for (String c : containerCaps) { // slices.Contains — O(n) scan
|
||||
count++;
|
||||
if (c.equals(cap)) { found = true; break; }
|
||||
}
|
||||
if (!found && !dedupDrop.containsKey(cap)) {
|
||||
dropList.add(cap);
|
||||
dedupDrop.put(cap, true);
|
||||
}
|
||||
}
|
||||
|
||||
// Find added: in containerCaps but not defaultCaps
|
||||
for (String cap : containerCaps) {
|
||||
boolean found = false;
|
||||
for (String c : defaultCaps) { // slices.Contains — O(n) scan
|
||||
count++;
|
||||
if (c.equals(cap)) { found = true; break; }
|
||||
}
|
||||
if (!found && !dedupAdd.containsKey(cap)) {
|
||||
addList.add(cap);
|
||||
dedupAdd.put(cap, true);
|
||||
}
|
||||
}
|
||||
|
||||
this.ops = count;
|
||||
this.drop = dropList;
|
||||
this.add = addList;
|
||||
}
|
||||
}
|
||||
|
||||
// ── Fast implementation ───────────────────────────────────────────────────
|
||||
static class FastCapDiff {
|
||||
final long ops;
|
||||
final List<String> drop;
|
||||
final List<String> add;
|
||||
|
||||
FastCapDiff(List<String> defaultCaps, List<String> containerCaps) {
|
||||
long count = 0;
|
||||
|
||||
// Build sets — O(n) each
|
||||
Set<String> defaultSet = new HashSet<>(defaultCaps.size() * 2);
|
||||
Set<String> containerSet = new HashSet<>(containerCaps.size() * 2);
|
||||
for (String c : defaultCaps) { count++; defaultSet.add(c); }
|
||||
for (String c : containerCaps) { count++; containerSet.add(c); }
|
||||
|
||||
List<String> dropList = new ArrayList<>();
|
||||
List<String> addList = new ArrayList<>();
|
||||
Set<String> dedupDrop = new HashSet<>();
|
||||
Set<String> dedupAdd = new HashSet<>();
|
||||
|
||||
for (String cap : defaultCaps) {
|
||||
count++; // O(1) set lookup
|
||||
if (!containerSet.contains(cap) && dedupDrop.add(cap)) {
|
||||
dropList.add(cap);
|
||||
}
|
||||
}
|
||||
for (String cap : containerCaps) {
|
||||
count++; // O(1) set lookup
|
||||
if (!defaultSet.contains(cap) && dedupAdd.add(cap)) {
|
||||
addList.add(cap);
|
||||
}
|
||||
}
|
||||
|
||||
this.ops = count;
|
||||
this.drop = dropList;
|
||||
this.add = addList;
|
||||
}
|
||||
}
|
||||
|
||||
// ── Node / Result ─────────────────────────────────────────────────────────
|
||||
static class Node {
|
||||
final String cap;
|
||||
Node(String cap) { this.cap = cap; }
|
||||
}
|
||||
|
||||
static class Result {
|
||||
final long slowOps, fastOps;
|
||||
final List<String> slowDrop, fastDrop;
|
||||
final List<String> slowAdd, fastAdd;
|
||||
|
||||
Result(long slowOps, long fastOps,
|
||||
List<String> slowDrop, List<String> fastDrop,
|
||||
List<String> slowAdd, List<String> fastAdd) {
|
||||
this.slowOps = slowOps; this.fastOps = fastOps;
|
||||
this.slowDrop = slowDrop; this.fastDrop = fastDrop;
|
||||
this.slowAdd = slowAdd; this.fastAdd = fastAdd;
|
||||
}
|
||||
}
|
||||
|
||||
// ── test helpers ──────────────────────────────────────────────────────────
|
||||
static int passed = 0, total = 0;
|
||||
|
||||
static void test(String name, boolean condition) {
|
||||
total++;
|
||||
if (condition) { passed++; System.out.println("PASS: " + name); }
|
||||
else { System.out.println("FAIL: " + name); }
|
||||
}
|
||||
|
||||
static List<String> caps(int n) {
|
||||
List<String> c = new ArrayList<>(n);
|
||||
for (int i = 0; i < n; i++) c.add("CAP_" + i);
|
||||
return c;
|
||||
}
|
||||
|
||||
static Result run(List<String> defaults, List<String> container) {
|
||||
SlowCapDiff slow = new SlowCapDiff(defaults, container);
|
||||
FastCapDiff fast = new FastCapDiff(defaults, container);
|
||||
return new Result(slow.ops, fast.ops,
|
||||
slow.drop, fast.drop,
|
||||
slow.add, fast.add);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
// T1: Realistic — N=41 default, N=41 container (some overlap)
|
||||
{
|
||||
List<String> defaults = caps(41);
|
||||
List<String> container = caps(41);
|
||||
// Container has 5 extra caps and dropped 5 defaults
|
||||
for (int i = 41; i < 46; i++) container.add("CAP_EXTRA_" + i);
|
||||
container.subList(0, 5).clear(); // remove first 5 defaults
|
||||
|
||||
Result r = run(defaults, container);
|
||||
test("T1-slow-quadratic [N=41]",
|
||||
r.slowOps >= 41L * 36 / 2); // at least partial n*m work
|
||||
test("T1-fast-linear [N=41]",
|
||||
r.fastOps <= 2 * 41 + 2 * 46 + 10);
|
||||
double speedup = (double) r.slowOps / r.fastOps;
|
||||
test("T1-speedup>=5x", speedup >= 5.0);
|
||||
System.out.printf(" slow=%d ops, fast=%d ops, speedup=%.1fx%n",
|
||||
r.slowOps, r.fastOps, speedup);
|
||||
List<String> sd = new ArrayList<>(r.slowDrop); Collections.sort(sd);
|
||||
List<String> fd = new ArrayList<>(r.fastDrop); Collections.sort(fd);
|
||||
test("T1-drop-results-match", sd.equals(fd));
|
||||
List<String> sa = new ArrayList<>(r.slowAdd); Collections.sort(sa);
|
||||
List<String> fa = new ArrayList<>(r.fastAdd); Collections.sort(fa);
|
||||
test("T1-add-results-match", sa.equals(fa));
|
||||
}
|
||||
|
||||
// T2: Large cap sets — N=200
|
||||
{
|
||||
List<String> defaults = caps(200);
|
||||
List<String> container = caps(200);
|
||||
for (int i = 200; i < 220; i++) container.add("CAP_EXTRA_" + i);
|
||||
container.subList(0, 20).clear();
|
||||
|
||||
Result r = run(defaults, container);
|
||||
double speedup = (double) r.slowOps / r.fastOps;
|
||||
test("T2-slow-quadratic [N=200]",
|
||||
r.slowOps >= 200L * 180 / 2);
|
||||
test("T2-fast-linear [N=200]",
|
||||
r.fastOps <= 2 * 200 + 2 * 220 + 10);
|
||||
test("T2-speedup>=20x", speedup >= 20.0);
|
||||
System.out.printf(" slow=%d ops, fast=%d ops, speedup=%.1fx%n",
|
||||
r.slowOps, r.fastOps, speedup);
|
||||
List<String> sd = new ArrayList<>(r.slowDrop); Collections.sort(sd);
|
||||
List<String> fd = new ArrayList<>(r.fastDrop); Collections.sort(fd);
|
||||
test("T2-drop-match", sd.equals(fd));
|
||||
List<String> sa = new ArrayList<>(r.slowAdd); Collections.sort(sa);
|
||||
List<String> fa = new ArrayList<>(r.fastAdd); Collections.sort(fa);
|
||||
test("T2-add-match", sa.equals(fa));
|
||||
}
|
||||
|
||||
// T3: Identical cap sets — nothing dropped or added
|
||||
{
|
||||
List<String> c = caps(41);
|
||||
Result r = run(c, new ArrayList<>(c));
|
||||
test("T3-identical-drop-empty", r.fastDrop.isEmpty());
|
||||
test("T3-identical-add-empty", r.fastAdd.isEmpty());
|
||||
test("T3-results-match-slow",
|
||||
r.slowDrop.equals(r.fastDrop) && r.slowAdd.equals(r.fastAdd));
|
||||
}
|
||||
|
||||
// T4: Completely disjoint sets
|
||||
{
|
||||
List<String> defaults = caps(20);
|
||||
List<String> container = new ArrayList<>();
|
||||
for (int i = 20; i < 40; i++) container.add("CAP_" + i);
|
||||
|
||||
Result r = run(defaults, container);
|
||||
// All defaults are dropped, all container caps are added
|
||||
test("T4-all-dropped", r.fastDrop.size() == 20);
|
||||
test("T4-all-added", r.fastAdd.size() == 20);
|
||||
List<String> sd = new ArrayList<>(r.slowDrop); Collections.sort(sd);
|
||||
List<String> fd = new ArrayList<>(r.fastDrop); Collections.sort(fd);
|
||||
test("T4-results-match", sd.equals(fd));
|
||||
}
|
||||
|
||||
System.out.println();
|
||||
System.out.printf("%d/%d PASS%n", passed, total);
|
||||
if (passed != total) System.exit(1);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue