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:
russell@unturf.com 2026-03-27 21:25:37 -04:00
parent dde5ec97fb
commit e4ee168b1e
50 changed files with 4775 additions and 5 deletions

View file

@ -0,0 +1,172 @@
package unit;
import java.util.*;
/**
* actix-0001: CWE-407 actix-web introspection update_unique O(R×G) Vec linear dedup.
*
* Simulates the defective update_unique() pattern from actix-web's
* introspection.rs:984-989:
*
* fn update_unique<T>(existing: &mut Vec<T>, new_items: &[T]) {
* for item in new_items {
* if !existing.contains(item) { // O(E) linear scan
* existing.push(item.clone());
* }
* }
* }
*
* Called once per route registration for guards, patterns, and methods vecs.
* With R routes sharing a scope and G unique guards accumulating, total work
* is O(R × G).
*
* Fix: pre-build a HashSet for O(1) membership, reducing to O(R + G).
*/
public class ActixUpdateUniqueAlgorithm {
static long slowOps = 0;
static long fastOps = 0;
// --- SLOW: Vec.contains() linear scan (actix-web defective pattern) ---
static void updateUniqueSlow(List<String> existing, List<String> newItems) {
for (String item : newItems) {
slowOps++;
boolean found = false;
for (String e : existing) { // O(E) inner scan
slowOps++;
if (e.equals(item)) {
found = true;
break;
}
}
if (!found) {
existing.add(item);
}
}
}
// --- FAST: HashSet membership check O(1) per item ---
static void updateUniqueFast(List<String> existing, Set<String> existingSet, List<String> newItems) {
for (String item : newItems) {
fastOps++;
if (!existingSet.contains(item)) {
existing.add(item);
existingSet.add(item);
}
}
}
// Simulate R route registrations, each contributing G guard names to a shared path's accumulator.
// In actix-web: register_pattern_detail() calls update_unique() for guards on each route.
static List<String> simulateSlow(int R, int G) {
List<String> accumulated = new ArrayList<>();
for (int r = 0; r < R; r++) {
List<String> routeGuards = new ArrayList<>();
for (int g = 0; g < G; g++) {
// Routes share some guards + add one unique guard each
routeGuards.add("guard_" + (g % (G / 2 + 1)));
}
routeGuards.add("route_guard_" + r);
updateUniqueSlow(accumulated, routeGuards);
}
return accumulated;
}
static List<String> simulateFast(int R, int G) {
List<String> accumulated = new ArrayList<>();
Set<String> accumulatedSet = new HashSet<>();
for (int r = 0; r < R; r++) {
List<String> routeGuards = new ArrayList<>();
for (int g = 0; g < G; g++) {
routeGuards.add("guard_" + (g % (G / 2 + 1)));
}
routeGuards.add("route_guard_" + r);
updateUniqueFast(accumulated, accumulatedSet, routeGuards);
}
return accumulated;
}
public static void main(String[] args) {
System.out.println("actix-0001: update_unique O(R×G) Vec linear dedup vs HashSet");
System.out.println("=============================================================");
int[] sizes = {50, 100, 200, 500};
int passes = 0;
int failures = 0;
for (int N : sizes) {
slowOps = 0;
fastOps = 0;
int R = N; // routes sharing a scope
int G = 20; // guards per route registration
List<String> slowResult = simulateSlow(R, G);
List<String> fastResult = simulateFast(R, G);
// Sort both for comparison
List<String> sortedSlow = new ArrayList<>(slowResult);
List<String> sortedFast = new ArrayList<>(fastResult);
Collections.sort(sortedSlow);
Collections.sort(sortedFast);
boolean match = sortedSlow.equals(sortedFast);
double ratio = slowOps > 0 ? (double) slowOps / Math.max(fastOps, 1) : 0;
String status = (match && ratio >= 5.0) ? "PASS" : "FAIL";
System.out.printf(" N=%3d routes, G=%2d guards/reg: slow=%7d ops fast=%6d ops ratio=%.1fx result_match=%s [%s]%n",
R, G, slowOps, fastOps, ratio, match, status);
if (match && ratio >= 5.0) {
passes++;
} else {
failures++;
if (!match) {
System.out.println(" ERROR: slow and fast results differ!");
System.out.println(" slow size=" + sortedSlow.size() + " fast size=" + sortedFast.size());
}
if (ratio < 5.0) {
System.out.printf(" ERROR: ratio %.1fx below required 5x minimum%n", ratio);
}
}
}
System.out.println();
// Larger test: G=50 guards per route (high guard density scenario)
System.out.println("High-density guard test (R=500, G=50 guards/reg):");
{
int R = 500;
int G = 50;
slowOps = 0;
fastOps = 0;
List<String> slowResult = simulateSlow(R, G);
List<String> fastResult = simulateFast(R, G);
List<String> sortedSlow = new ArrayList<>(slowResult);
List<String> sortedFast = new ArrayList<>(fastResult);
Collections.sort(sortedSlow);
Collections.sort(sortedFast);
boolean match = sortedSlow.equals(sortedFast);
double ratio = (double) slowOps / Math.max(fastOps, 1);
String status = (match && ratio >= 5.0) ? "PASS" : "FAIL";
System.out.printf(" R=%d routes, G=%d: slow=%d ops fast=%d ops ratio=%.1fx match=%s [%s]%n",
R, G, slowOps, fastOps, ratio, match, status);
if (match && ratio >= 5.0) passes++;
else failures++;
}
System.out.println();
System.out.printf("%d/%d PASS%n", passes, passes + failures);
if (failures > 0) {
System.exit(1);
}
}
}