import java.util.*; /** * CWE-407 unit test for Asterisk app_queue.c defect. * * asterisk-0001: apps/app_queue.c interface_exists() * ao2_iterator_init + while(ao2_iterator_next) + strcasecmp — O(M) walk * over all queue members to find one by interface string. * Fix: ao2_find(q->members, interface, OBJ_KEY) — O(1) hash lookup using * the container's existing key function (members already keyed by interface). */ public class AsteriskTest { // Simulate defect: O(M) iterator walk static String interfaceExists_iterator(List members, String iface) { for (String m : members) { // O(M) linear scan if (m.equalsIgnoreCase(iface)) return m; } return null; } // Simulate fix: O(1) hash lookup static String interfaceExists_ao2find(Map membersMap, String iface) { return membersMap.get(iface.toLowerCase()); // O(1) } static void testAsterisk0001() throws Exception { int M = 2000; // queue members List members = new ArrayList<>(); Map membersMap = new HashMap<>(); for (int i = 0; i < M; i++) { String iface = "SIP/agent-" + String.format("%04d", i); members.add(iface); membersMap.put(iface.toLowerCase(), iface); } // target near end of list (worst case for linear scan) String target = "SIP/agent-" + String.format("%04d", M - 1); // correctness String r1 = interfaceExists_iterator(members, target); String r2 = interfaceExists_ao2find(membersMap, target); assert r1 != null && r1.equalsIgnoreCase(target) : "iterator must find target"; assert r2 != null && r2.equalsIgnoreCase(target) : "ao2find must find target"; assert interfaceExists_iterator(members, "SIP/nonexistent") == null; assert interfaceExists_ao2find(membersMap, "SIP/nonexistent") == null; // performance: simulate C calls per second int REPS = 20_000; long t0 = System.nanoTime(); for (int r = 0; r < REPS; r++) interfaceExists_iterator(members, target); long tIter = System.nanoTime() - t0; t0 = System.nanoTime(); for (int r = 0; r < REPS; r++) interfaceExists_ao2find(membersMap, target); long tHash = System.nanoTime() - t0; double ratio = (double) tIter / tHash; System.out.printf("asterisk-0001: iter=%.3fs ao2find=%.3fs ratio=%.1f×%n", tIter / 1e9, tHash / 1e9, ratio); assert ratio > 10 : "Expected >10× speedup, got " + ratio; System.out.println("PASS asterisk-0001"); } public static void main(String[] args) throws Exception { testAsterisk0001(); System.out.println("ALL PASS"); } }