578/240 — rustc-0004/vertx-0001/asterisk-0003/bitcoin-0001/actix-web-0003/hazelcast-0001+0002/rabbitmq-0005/nginx-0003/haproxy-0003/envoy-0003/istio-0003
This commit is contained in:
parent
dde5ec97fb
commit
e4ee168b1e
50 changed files with 4775 additions and 5 deletions
180
defects/asterisk/unit/CdrVarMergeAlgorithm.java
Normal file
180
defects/asterisk/unit/CdrVarMergeAlgorithm.java
Normal file
|
|
@ -0,0 +1,180 @@
|
|||
package unit;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* CWE-407 unit test: asterisk-0003
|
||||
*
|
||||
* Models cdr_object_create_public_records() variable merge.
|
||||
* SLOW: nested list traversal with strcasecmp — O(B × V)
|
||||
* FAST: hash set membership check — O(B + V)
|
||||
*/
|
||||
public class CdrVarMergeAlgorithm {
|
||||
|
||||
static long slowOps = 0;
|
||||
static long fastOps = 0;
|
||||
|
||||
/** Simulated variable: name -> value pair */
|
||||
static class Var {
|
||||
String name;
|
||||
String value;
|
||||
Var(String name, String value) { this.name = name; this.value = value; }
|
||||
}
|
||||
|
||||
/**
|
||||
* SLOW path: nested linear scan to deduplicate variables.
|
||||
* Models the defective AST_LIST_TRAVERSE inside AST_LIST_TRAVERSE.
|
||||
*
|
||||
* @param partyAVars already in varshead
|
||||
* @param partyBVars party_b variables to merge in
|
||||
* @return merged list
|
||||
*/
|
||||
static List<Var> mergeVarsSlow(List<Var> partyAVars, List<Var> partyBVars) {
|
||||
List<Var> varshead = new ArrayList<>(partyAVars);
|
||||
|
||||
for (Var bVar : partyBVars) { // outer: B iterations
|
||||
boolean found = false;
|
||||
for (Var existing : varshead) { // inner: V iterations — O(B×V)
|
||||
slowOps++;
|
||||
if (bVar.name.equalsIgnoreCase(existing.name)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
varshead.add(new Var(bVar.name, bVar.value));
|
||||
}
|
||||
}
|
||||
return varshead;
|
||||
}
|
||||
|
||||
/**
|
||||
* FAST path: hash set membership check — O(B + V).
|
||||
* Fix: build a HashMap of existing names first, then check in O(1).
|
||||
*
|
||||
* @param partyAVars already in varshead
|
||||
* @param partyBVars party_b variables to merge in
|
||||
* @return merged list
|
||||
*/
|
||||
static List<Var> mergeVarsFast(List<Var> partyAVars, List<Var> partyBVars) {
|
||||
List<Var> varshead = new ArrayList<>(partyAVars);
|
||||
HashMap<String, Boolean> existingNames = new HashMap<>();
|
||||
|
||||
for (Var v : partyAVars) { // O(V) build
|
||||
fastOps++;
|
||||
existingNames.put(v.name.toLowerCase(), Boolean.TRUE);
|
||||
}
|
||||
|
||||
for (Var bVar : partyBVars) { // outer: B iterations
|
||||
fastOps++; // O(1) lookup
|
||||
if (!existingNames.containsKey(bVar.name.toLowerCase())) {
|
||||
varshead.add(new Var(bVar.name, bVar.value));
|
||||
existingNames.put(bVar.name.toLowerCase(), Boolean.TRUE);
|
||||
}
|
||||
}
|
||||
return varshead;
|
||||
}
|
||||
|
||||
static boolean runTest(int numVarsA, int numVarsB, int overlap) {
|
||||
// Build party_a vars: var_a_0 ... var_a_(numVarsA-1)
|
||||
List<Var> partyA = new ArrayList<>();
|
||||
for (int i = 0; i < numVarsA; i++) {
|
||||
partyA.add(new Var("var_a_" + i, "val_a_" + i));
|
||||
}
|
||||
|
||||
// Build party_b vars: first 'overlap' vars share names with party_a
|
||||
// rest are unique to party_b
|
||||
List<Var> partyB = new ArrayList<>();
|
||||
for (int i = 0; i < overlap; i++) {
|
||||
partyB.add(new Var("var_a_" + i, "val_b_" + i)); // duplicate
|
||||
}
|
||||
for (int i = 0; i < numVarsB - overlap; i++) {
|
||||
partyB.add(new Var("var_b_" + i, "val_b_" + i)); // unique
|
||||
}
|
||||
|
||||
long slowBefore = slowOps;
|
||||
long fastBefore = fastOps;
|
||||
|
||||
List<Var> slowResult = mergeVarsSlow(partyA, partyB);
|
||||
List<Var> fastResult = mergeVarsFast(partyA, partyB);
|
||||
|
||||
long slowCount = slowOps - slowBefore;
|
||||
long fastCount = fastOps - fastBefore;
|
||||
|
||||
// Both should produce same merged count: numVarsA + (numVarsB - overlap) unique vars
|
||||
int expectedSize = numVarsA + (numVarsB - overlap);
|
||||
if (slowResult.size() != expectedSize) {
|
||||
System.out.println("FAIL: slow result size " + slowResult.size() + " expected " + expectedSize);
|
||||
return false;
|
||||
}
|
||||
if (fastResult.size() != expectedSize) {
|
||||
System.out.println("FAIL: fast result size " + fastResult.size() + " expected " + expectedSize);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Slow ops should be at least numVarsB (inner loop on each), approx numVarsB * numVarsA
|
||||
// Fast ops should be at most numVarsA + numVarsB
|
||||
double ratio = (double) slowCount / (double) fastCount;
|
||||
|
||||
System.out.printf(" N=%d B=%d overlap=%d | slowOps=%d fastOps=%d ratio=%.1fx%n",
|
||||
numVarsA, numVarsB, overlap, slowCount, fastCount, ratio);
|
||||
|
||||
if (ratio < 5.0) {
|
||||
System.out.printf("FAIL: ratio %.1fx < 5x threshold%n", ratio);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
int pass = 0;
|
||||
int fail = 0;
|
||||
|
||||
System.out.println("=== asterisk-0003: CDR Variable Merge O(B×V) ===");
|
||||
System.out.println();
|
||||
|
||||
// Test cases: (numVarsA, numVarsB, overlap)
|
||||
int[][] tests = {
|
||||
{20, 20, 5},
|
||||
{50, 50, 10},
|
||||
{100, 100, 20},
|
||||
{200, 200, 50},
|
||||
{500, 500, 100},
|
||||
};
|
||||
|
||||
for (int[] t : tests) {
|
||||
slowOps = 0;
|
||||
fastOps = 0;
|
||||
boolean ok = runTest(t[0], t[1], t[2]);
|
||||
if (ok) { pass++; } else { fail++; }
|
||||
}
|
||||
|
||||
System.out.println();
|
||||
|
||||
// Verify quadratic growth in slow path
|
||||
System.out.println("Quadratic growth verification (slow path):");
|
||||
for (int n : new int[]{10, 50, 100, 200}) {
|
||||
slowOps = 0;
|
||||
fastOps = 0;
|
||||
mergeVarsSlow(buildVarList("a", n), buildVarList("b", n));
|
||||
System.out.printf(" N=%d slow_ops=%d (expected ~%d quadratic)%n",
|
||||
n, slowOps, n * n);
|
||||
}
|
||||
|
||||
System.out.println();
|
||||
System.out.printf("%d/%d PASS%n", pass, pass + fail);
|
||||
if (fail > 0) {
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
static List<Var> buildVarList(String prefix, int n) {
|
||||
List<Var> list = new ArrayList<>();
|
||||
for (int i = 0; i < n; i++) {
|
||||
list.add(new Var(prefix + "_var_" + i, "val_" + i));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue