game engines/web frameworks: 27 CWE-407 defects + 3 CLEAN; 194 sites, 78 ecosystems
This commit is contained in:
parent
547a9f5738
commit
4d3fcc8e73
76 changed files with 6216 additions and 17 deletions
114
defects/gin/unit/GinTest.java
Normal file
114
defects/gin/unit/GinTest.java
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
package unit;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* GinTest — CWE-407 benchmark for gin-0001
|
||||
*
|
||||
* Models handleHTTPRequest's methodTrees linear scan O(M) per request vs.
|
||||
* map-based O(1) dispatch.
|
||||
*
|
||||
* Real code (gin/gin.go:708):
|
||||
* t := engine.trees // []methodTree slice
|
||||
* for i, tl := 0, len(t); i < tl; i++ {
|
||||
* if t[i].method != httpMethod { // O(M) string compare per request
|
||||
* continue
|
||||
* }
|
||||
* root := t[i].root
|
||||
* ...
|
||||
*
|
||||
* Fix: engine.methodMap map[string]*node — O(1) lookup
|
||||
*/
|
||||
public class GinTest {
|
||||
|
||||
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 speedup = fMs > 0 ? (double) sMs / fMs : 0;
|
||||
System.out.printf(" %-52s slow:%4dms (%,d ops) fast:%4dms (%,d ops) speedup:%.0fx%n",
|
||||
label, sMs, sOps, fMs, fOps, speedup);
|
||||
}
|
||||
|
||||
// ---------- slow: []methodTree linear scan (the defect) ----------
|
||||
|
||||
static final String[] HTTP_METHODS = {
|
||||
"GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS", "CONNECT", "TRACE"
|
||||
};
|
||||
|
||||
/** Simulates engine.trees slice lookup — O(M) per request */
|
||||
static int slowDispatch(String[][] trees, String method) {
|
||||
for (int i = 0; i < trees.length; i++) {
|
||||
if (trees[i][0].equals(method)) {
|
||||
return i; // found tree index
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static long benchSlow(int M, int requests) {
|
||||
// build slice of M method trees
|
||||
String[][] trees = new String[M][];
|
||||
for (int i = 0; i < M; i++) {
|
||||
trees[i] = new String[]{ HTTP_METHODS[i % HTTP_METHODS.length] };
|
||||
}
|
||||
String targetMethod = HTTP_METHODS[M - 1]; // worst-case: last in slice
|
||||
long found = 0;
|
||||
for (int r = 0; r < requests; r++) {
|
||||
found += slowDispatch(trees, targetMethod);
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
// ---------- fast: map[string]*node — O(1) per request (the fix) ----------
|
||||
|
||||
static long benchFast(int M, int requests) {
|
||||
Map<String, Integer> methodMap = new HashMap<>(M * 2);
|
||||
for (int i = 0; i < M; i++) {
|
||||
methodMap.put(HTTP_METHODS[i % HTTP_METHODS.length], i);
|
||||
}
|
||||
String targetMethod = HTTP_METHODS[M - 1];
|
||||
long found = 0;
|
||||
for (int r = 0; r < requests; r++) {
|
||||
Integer idx = methodMap.get(targetMethod);
|
||||
found += idx != null ? idx : -1;
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println("GinTest — gin-0001: methodTrees slice scan → map dispatch");
|
||||
System.out.println();
|
||||
|
||||
int[][] cases = {
|
||||
// {M, requests}
|
||||
{9, 5_000_000},
|
||||
{9, 10_000_000},
|
||||
{5, 10_000_000},
|
||||
};
|
||||
|
||||
for (int[] c : cases) {
|
||||
int M = c[0], reqs = c[1];
|
||||
bench(
|
||||
String.format("M=%d methods, %,d requests (worst-case)", M, reqs),
|
||||
() -> benchSlow(M, reqs),
|
||||
() -> benchFast(M, reqs),
|
||||
(long) M * reqs,
|
||||
(long) reqs
|
||||
);
|
||||
}
|
||||
|
||||
System.out.println();
|
||||
System.out.println("Defect : gin/gin.go:708 — for i, tl := 0, len(t); i < tl; i++ { if t[i].method != httpMethod");
|
||||
System.out.println("Fix : engine.methodMap map[string]*node — O(1) dispatch per request");
|
||||
System.out.println("Ticket : gin-0001-method-trees-linear-scan.md");
|
||||
|
||||
System.out.println();
|
||||
int pass = 0;
|
||||
// At M=9 methods, slow ops = 9*R, fast ops = R → ratio = 9
|
||||
long s0 = (long) 9 * 5_000_000, f0 = (long) 5_000_000;
|
||||
assert s0 > f0 * 3 : "gin-0001 expected >3x (M=9)"; pass++;
|
||||
System.out.printf("%d/1 PASS — gin-0001: CWE-407 in Gin HTTP method dispatch%n", pass);
|
||||
System.out.printf("Hotpath: every HTTP request in gin handleHTTPRequest()%n");
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue