java-topology/defects/asterisk/unit/AsteriskTest.java
russell@unturf.com ff6292d067 wave17: postgres-0001/asterisk-0001/haproxy-0001/nginx-0001; postfix+bevy CLEAN
postgres-0001: pg_inherits.c typeInheritsFrom() BFS visited List → HTAB O(1)
asterisk-0001: app_queue.c interface_exists() ao2_iterator walk → ao2_find O(1)
haproxy-0001: http_ana.c cookie-server scan linked-list → eb-tree index O(log S)
nginx-0001: ngx_http_link_multi_headers() O(H²) double-scan → O(H) hash pass
postfix: CLEAN (htable throughout; two marginal LOW admin-bounded candidates)
bevy: CLEAN (FixedBitSet/HashSet throughout; only hardware-bounded marginals)
2026-03-30 07:57:30 -04:00

69 lines
2.8 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.

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<String> 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<String, String> membersMap, String iface) {
return membersMap.get(iface.toLowerCase()); // O(1)
}
static void testAsterisk0001() throws Exception {
int M = 2000; // queue members
List<String> members = new ArrayList<>();
Map<String, String> 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");
}
}