wave17 complete: systemd/emacs/vim/qemu/tcl/kafka-0007/spark-0004 + 559/240

This commit is contained in:
russell@unturf.com 2026-03-27 20:15:47 -04:00
parent 4221966e66
commit cce7ec653a
32 changed files with 3007 additions and 5 deletions

View file

@ -0,0 +1,196 @@
package unit;
import java.util.*;
/**
* CWE-407 unit test: systemd-0002
*
* unit_file_get_list() calls strv_contains(states, unit_file_state_to_string(state))
* for every unit file found on disk. strv_contains is O(S) linear scan over the
* states filter array. Total cost: O(U × S) where U = unit files, S = state filters.
*
* Fix: build a HashSet from the states array before the loop O(1) lookup per unit.
*/
public class SystemdUnitFileGetListTest {
// Enum representing systemd UnitFileState values
enum UnitFileState {
ENABLED, DISABLED, STATIC, MASKED, LINKED, INDIRECT,
ENABLED_RUNTIME, LINKED_RUNTIME, ALIAS, GENERATED,
TRANSIENT, BAD
}
static UnitFileState[] ALL_STATES = UnitFileState.values();
// -----------------------------------------------------------------------
// SLOW path: simulates the defective strv_contains check per unit file
// -----------------------------------------------------------------------
static long slowFilter(String[] unitFiles, String[] states) {
long ops = 0;
List<String> matched = new ArrayList<>();
for (String unit : unitFiles) {
// Assign a state (deterministic from unit name hash)
UnitFileState state = ALL_STATES[Math.abs(unit.hashCode()) % ALL_STATES.length];
String stateStr = state.name().toLowerCase();
// O(S) linear scan strv_contains equivalent
boolean found = false;
for (String s : states) {
ops++;
if (stateStr.equals(s)) {
found = true;
break;
}
}
if (found) matched.add(unit);
}
return ops;
}
// -----------------------------------------------------------------------
// FAST path: HashSet built once, O(1) lookup per unit
// -----------------------------------------------------------------------
static long fastFilter(String[] unitFiles, String[] states) {
long ops = 0;
Set<String> stateSet = new HashSet<>(Arrays.asList(states));
List<String> matched = new ArrayList<>();
for (String unit : unitFiles) {
UnitFileState state = ALL_STATES[Math.abs(unit.hashCode()) % ALL_STATES.length];
String stateStr = state.name().toLowerCase();
ops++; // single hash lookup
if (stateSet.contains(stateStr)) matched.add(unit);
}
return ops;
}
// -----------------------------------------------------------------------
// Helpers
// -----------------------------------------------------------------------
static String[] makeUnits(int n) {
String[] a = new String[n];
for (int i = 0; i < n; i++) a[i] = "unit-" + i + ".service";
return a;
}
static String[] makeStates(int s) {
String[] a = new String[s];
String[] names = {"enabled", "disabled", "static", "masked", "linked"};
for (int i = 0; i < s; i++) a[i] = names[i % names.length];
return a;
}
// Count matching results identically for both paths for correctness check
static Set<String> matchedSet(String[] unitFiles, String[] states) {
Set<String> stateSet = new HashSet<>(Arrays.asList(states));
Set<String> matched = new LinkedHashSet<>();
for (String unit : unitFiles) {
UnitFileState state = ALL_STATES[Math.abs(unit.hashCode()) % ALL_STATES.length];
if (stateSet.contains(state.name().toLowerCase())) matched.add(unit);
}
return matched;
}
// -----------------------------------------------------------------------
// Tests
// -----------------------------------------------------------------------
static int pass = 0;
static int fail = 0;
static void check(String name, boolean condition) {
if (condition) {
System.out.println("PASS: " + name);
pass++;
} else {
System.out.println("FAIL: " + name);
fail++;
}
}
// Slow path variant that always scans full list (no early exit) to measure worst case
static long slowFilterWorstCase(String[] unitFiles, String[] states) {
long ops = 0;
for (String unit : unitFiles) {
// Assign a state that never matches any filter (simulates "bad"/"transient" units)
String stateStr = "bad"; // last state, never in typical filter lists
for (String s : states) {
ops++;
if (stateStr.equals(s)) break; // never breaks scans all S
}
}
return ops;
}
static long fastFilterWorstCase(String[] unitFiles, String[] states) {
long ops = 0;
Set<String> stateSet = new HashSet<>(Arrays.asList(states));
for (String unit : unitFiles) {
ops++; // one hash lookup per unit, regardless of match
}
return ops;
}
static void testCase(int numUnits, int numStates) {
String[] units = makeUnits(numUnits);
String[] states = makeStates(numStates);
// Worst case: every unit has state NOT in filter, slow path scans all S per unit
long slowOps = slowFilterWorstCase(units, states);
long fastOps = fastFilterWorstCase(units, states);
double ratio = (double) slowOps / fastOps;
System.out.printf(" U=%d S=%d: slowOps=%d fastOps=%d ratio=%.1fx%n",
numUnits, numStates, slowOps, fastOps, ratio);
check("U=" + numUnits + " S=" + numStates + ": slowOps == U*S",
slowOps == (long) numUnits * numStates);
check("U=" + numUnits + " S=" + numStates + ": fastOps == numUnits", fastOps == numUnits);
check("U=" + numUnits + " S=" + numStates + ": slowOps/fastOps >= 5x", ratio >= 5.0);
}
static void testCorrectness() {
// Small case: 6 units, filter for "enabled" and "static"
String[] units = new String[12];
for (int i = 0; i < 12; i++) units[i] = "svc-" + i + ".service";
String[] states = {"enabled", "static"};
// Run both paths and compare matched counts
Set<String> expected = matchedSet(units, states);
// Slow path result
Set<String> slowMatched = new LinkedHashSet<>();
Set<String> stateSet = new HashSet<>(Arrays.asList(states));
for (String unit : units) {
UnitFileState state = ALL_STATES[Math.abs(unit.hashCode()) % ALL_STATES.length];
String stateStr = state.name().toLowerCase();
for (String s : states) {
if (stateStr.equals(s)) { slowMatched.add(unit); break; }
}
}
check("correctness: slow matches expected", slowMatched.equals(expected));
// Fast path result
Set<String> fastMatched = new LinkedHashSet<>();
for (String unit : units) {
UnitFileState state = ALL_STATES[Math.abs(unit.hashCode()) % ALL_STATES.length];
if (stateSet.contains(state.name().toLowerCase())) fastMatched.add(unit);
}
check("correctness: fast matches expected", fastMatched.equals(expected));
check("correctness: slow equals fast", slowMatched.equals(fastMatched));
}
// -----------------------------------------------------------------------
// Main
// -----------------------------------------------------------------------
public static void main(String[] args) {
System.out.println("=== systemd-0002: unit_file_get_list states filter O(U*S) → O(U) ===");
testCorrectness();
testCase(1000, 5);
testCase(2000, 5);
testCase(5000, 10);
System.out.println();
System.out.printf("%d/%d PASS%n", pass, pass + fail);
if (fail > 0) System.exit(1);
}
}