67 lines
2.6 KiB
Java
67 lines
2.6 KiB
Java
package unit;
|
|
|
|
import java.util.*;
|
|
|
|
/**
|
|
* FastAPITest — fastapi-0001
|
|
*
|
|
* Proves CWE-407 in FastAPI:
|
|
* fastapi-0001: dependencies/utils.py:142 — get_flat_dependant() uses
|
|
* visited: list[DependencyCacheKey]; membership test O(D) per node;
|
|
* O(D²) total for D-node dependency chain.
|
|
* Fix: visited → set; O(1) per check.
|
|
*
|
|
* Run: javac -d . FastAPITest.java && java -ea unit.FastAPITest
|
|
*/
|
|
public class FastAPITest {
|
|
|
|
/** SLOW: visited as List — O(D) per contains check; O(D²) for D deps. Returns op count. */
|
|
static long flattenSlow(int D) {
|
|
List<Integer> visited = new ArrayList<>();
|
|
long ops = 0;
|
|
for (int idx = 0; idx < D; idx++) {
|
|
// simulate: if skip_repeats and sub_dependant.cache_key in visited — O(N)
|
|
for (int j = 0; j < visited.size(); j++) { ops++; if (visited.get(j).equals(idx)) break; }
|
|
visited.add(idx);
|
|
}
|
|
return ops;
|
|
}
|
|
|
|
/** FAST: visited as Set — O(1) per add/contains check; O(D) total. Returns op count. */
|
|
static long flattenFast(int D) {
|
|
Set<Integer> visited = new HashSet<>();
|
|
long ops = 0;
|
|
for (int idx = 0; idx < D; idx++) {
|
|
ops++; // O(1) set membership
|
|
visited.add(idx);
|
|
}
|
|
return ops;
|
|
}
|
|
|
|
static void bench(String label, Runnable slow, Runnable fast, long sOps, long fOps) {
|
|
slow.run(); fast.run();
|
|
long t0 = System.nanoTime(); slow.run(); long sMs = (System.nanoTime()-t0)/1_000_000;
|
|
long t1 = System.nanoTime(); fast.run(); long fMs = (System.nanoTime()-t1)/1_000_000;
|
|
double r = fOps > 0 ? (double)sOps/fOps : 0;
|
|
System.out.printf(" %-52s slow:%4dms (%,d ops) fast:%4dms (%,d ops) speedup:%.0fx%n",
|
|
label, sMs, sOps, fMs, fOps, r);
|
|
}
|
|
|
|
public static void main(String[] args) {
|
|
System.out.println("=== UNIT fastapi-0001: FastAPI CWE-407 ===");
|
|
System.out.println();
|
|
|
|
final int D = 1000; // 1000-node dependency graph (large FastAPI app)
|
|
|
|
long s0 = flattenSlow(D), f0 = flattenFast(D);
|
|
bench("fastapi-0001 get_flat_dependant visited list D=1000",
|
|
() -> flattenSlow(D), () -> flattenFast(D), s0, f0);
|
|
|
|
System.out.println();
|
|
int pass = 0;
|
|
assert s0 > f0 * 50 : "fastapi-0001 expected >50x; slow=" + s0 + " fast=" + f0; pass++;
|
|
|
|
System.out.printf("%d/1 PASS — fastapi-0001: CWE-407 in FastAPI dependency resolver%n", pass);
|
|
System.out.printf("Hotpath: get_flat_dependant() at route registration and /openapi.json%n");
|
|
}
|
|
}
|