terraform-0001: Tarjan SCC inStack linear scan O(E*V) — HIGH, 994x at V=2000 ansible-0002: Host.add_group() list membership O(A*G) — MEDIUM, 499x at G=1000 ansible-0003: Handler.notify_host() list membership O(H^2) — MEDIUM, 499x at H=1000
132 lines
4.5 KiB
Java
132 lines
4.5 KiB
Java
import java.util.*;
|
|
|
|
/**
|
|
* CWE-407 unit tests for ansible-0002 and ansible-0003.
|
|
*
|
|
* ansible-0002: Host.add_group() uses `group not in self.groups` list scan O(G)
|
|
* inside ancestor loop — O(A*G) per call, O(H*G*A) total.
|
|
*
|
|
* ansible-0003: Handler.is_host_notified() uses `host in self.notified_hosts`
|
|
* list scan — O(H) per notify, O(H^2) total.
|
|
*
|
|
* Fix: set alongside list for O(1) membership.
|
|
*/
|
|
public class AnsibleTest {
|
|
|
|
static long ops;
|
|
|
|
// ===== ansible-0002: Host.add_group linear scan =====
|
|
|
|
/** Simulates adding G groups to a host, each with some ancestors */
|
|
static long hostAddGroupDefective(int G) {
|
|
ops = 0;
|
|
List<String> hostGroups = new ArrayList<>(); // self.groups as list
|
|
|
|
for (int g = 0; g < G; g++) {
|
|
// Simulate: group not in self.groups (linear scan)
|
|
boolean found = false;
|
|
for (String existing : hostGroups) {
|
|
ops++;
|
|
if (existing.equals("group-" + g)) { found = true; break; }
|
|
}
|
|
if (!found) {
|
|
hostGroups.add("group-" + g);
|
|
}
|
|
}
|
|
return ops;
|
|
}
|
|
|
|
static long hostAddGroupFixed(int G) {
|
|
ops = 0;
|
|
List<String> hostGroups = new ArrayList<>();
|
|
Set<String> hostGroupsSet = new HashSet<>();
|
|
|
|
for (int g = 0; g < G; g++) {
|
|
ops++; // HashSet.contains = O(1), count as 1 op
|
|
if (!hostGroupsSet.contains("group-" + g)) {
|
|
hostGroups.add("group-" + g);
|
|
hostGroupsSet.add("group-" + g);
|
|
}
|
|
}
|
|
return ops;
|
|
}
|
|
|
|
// ===== ansible-0003: Handler.notify_host linear scan =====
|
|
|
|
/** Simulates notifying H hosts on a handler */
|
|
static long handlerNotifyDefective(int H) {
|
|
ops = 0;
|
|
List<String> notifiedHosts = new ArrayList<>(); // self.notified_hosts as list
|
|
|
|
for (int h = 0; h < H; h++) {
|
|
String host = "host-" + h;
|
|
// is_host_notified: host in self.notified_hosts (linear scan)
|
|
boolean found = false;
|
|
for (String existing : notifiedHosts) {
|
|
ops++;
|
|
if (existing.equals(host)) { found = true; break; }
|
|
}
|
|
if (!found) {
|
|
notifiedHosts.add(host);
|
|
}
|
|
}
|
|
return ops;
|
|
}
|
|
|
|
static long handlerNotifyFixed(int H) {
|
|
ops = 0;
|
|
List<String> notifiedHosts = new ArrayList<>();
|
|
Set<String> notifiedSet = new HashSet<>();
|
|
|
|
for (int h = 0; h < H; h++) {
|
|
String host = "host-" + h;
|
|
ops++; // HashSet.contains = O(1)
|
|
if (!notifiedSet.contains(host)) {
|
|
notifiedHosts.add(host);
|
|
notifiedSet.add(host);
|
|
}
|
|
}
|
|
return ops;
|
|
}
|
|
|
|
public static void main(String[] args) {
|
|
int[] sizes = {200, 500, 1000};
|
|
boolean allPass = true;
|
|
|
|
// --- ansible-0002 ---
|
|
System.out.println("ansible-0002: Host.add_group() list membership scan");
|
|
System.out.println("===================================================");
|
|
System.out.printf("%-8s %14s %14s %10s %s%n",
|
|
"G", "Defect(ops)", "Fixed(ops)", "Ratio", "Status");
|
|
|
|
for (int G : sizes) {
|
|
long dOps = hostAddGroupDefective(G);
|
|
long fOps = hostAddGroupFixed(G);
|
|
double ratio = (double) dOps / Math.max(fOps, 1);
|
|
String status = (ratio >= 5.0) ? "PASS" : "FAIL";
|
|
if (!status.equals("PASS")) allPass = false;
|
|
System.out.printf("%-8d %14d %14d %10.1fx %s%n", G, dOps, fOps, ratio, status);
|
|
}
|
|
|
|
System.out.println();
|
|
|
|
// --- ansible-0003 ---
|
|
System.out.println("ansible-0003: Handler.notify_host() list membership scan");
|
|
System.out.println("=======================================================");
|
|
System.out.printf("%-8s %14s %14s %10s %s%n",
|
|
"H", "Defect(ops)", "Fixed(ops)", "Ratio", "Status");
|
|
|
|
for (int H : sizes) {
|
|
long dOps = handlerNotifyDefective(H);
|
|
long fOps = handlerNotifyFixed(H);
|
|
double ratio = (double) dOps / Math.max(fOps, 1);
|
|
String status = (ratio >= 5.0) ? "PASS" : "FAIL";
|
|
if (!status.equals("PASS")) allPass = false;
|
|
System.out.printf("%-8d %14d %14d %10.1fx %s%n", H, dOps, fOps, ratio, status);
|
|
}
|
|
|
|
System.out.println();
|
|
System.out.println(allPass ? "ALL PASS" : "SOME FAIL");
|
|
System.exit(allPass ? 0 : 1);
|
|
}
|
|
}
|