package unit; import java.util.*; /** * FiberTest — CWE-407 benchmark for fiber-0001 * * Models Bind.Body()'s O(B×M) nested scan for custom binder MIME dispatch * vs. O(1) map-based dispatch. * * Real code (fiber/bind.go:391): * for _, customBinder := range binders { * if slices.Contains(customBinder.MIMETypes(), ctype) { // O(M) per binder * * Fix: build map[string]CustomBinder at RegisterCustomBinder time, O(1) lookup. * * Also models Bind.Custom()'s O(B) name scan (bind.go:216). */ public class FiberTest { 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: nested slice scan (the defect) ---------- /** Simulates slices.Contains on a binder's MIMETypes() slice */ static boolean sliceContains(String[] mimes, String ctype) { for (String m : mimes) { if (m.equals(ctype)) return true; } return false; } /** Simulates Bind.Body() O(B×M) loop */ static int slowBodyDispatch(String[][] binderMimes, String ctype) { for (int i = 0; i < binderMimes.length; i++) { if (sliceContains(binderMimes[i], ctype)) { return i; } } return -1; } /** Simulates Bind.Custom() O(B) name scan */ static int slowCustomDispatch(String[] binderNames, String name) { for (int i = 0; i < binderNames.length; i++) { if (binderNames[i].equals(name)) return i; } return -1; } static long benchBodySlow(int B, int M, int requests) { String[][] binderMimes = new String[B][]; for (int b = 0; b < B; b++) { binderMimes[b] = new String[M]; for (int m = 0; m < M; m++) { binderMimes[b][m] = "application/type-" + b + "-" + m; } } String target = binderMimes[B - 1][M - 1]; // worst-case long found = 0; for (int r = 0; r < requests; r++) { found += slowBodyDispatch(binderMimes, target); } return found; } // ---------- fast: map lookup (the fix) ---------- static long benchBodyFast(int B, int M, int requests) { Map mimeMap = new HashMap<>(B * M * 2); for (int b = 0; b < B; b++) { for (int m = 0; m < M; m++) { mimeMap.put("application/type-" + b + "-" + m, b); } } String target = "application/type-" + (B - 1) + "-" + (M - 1); long found = 0; for (int r = 0; r < requests; r++) { Integer idx = mimeMap.get(target); found += idx != null ? idx : -1; } return found; } static long benchCustomSlow(int B, int requests) { String[] names = new String[B]; for (int b = 0; b < B; b++) names[b] = "binder-" + b; String target = names[B - 1]; long found = 0; for (int r = 0; r < requests; r++) { found += slowCustomDispatch(names, target); } return found; } static long benchCustomFast(int B, int requests) { Map nameMap = new HashMap<>(B * 2); for (int b = 0; b < B; b++) nameMap.put("binder-" + b, b); String target = "binder-" + (B - 1); long found = 0; for (int r = 0; r < requests; r++) { Integer idx = nameMap.get(target); found += idx != null ? idx : -1; } return found; } public static void main(String[] args) { System.out.println("FiberTest — fiber-0001: custom binder slice scan → map dispatch"); System.out.println(); System.out.println(" [Body() MIME dispatch — bind.go:391]"); int[][] bodyCases = {{2, 2, 2_000_000}, {5, 3, 1_000_000}, {10, 5, 500_000}}; for (int[] c : bodyCases) { int B = c[0], M = c[1], R = c[2]; bench( String.format("B=%d binders, M=%d MIMEs each, %,d requests", B, M, R), () -> benchBodySlow(B, M, R), () -> benchBodyFast(B, M, R), (long) B * M * R, (long) R ); } System.out.println(); System.out.println(" [Custom() name dispatch — bind.go:216]"); int[][] customCases = {{5, 2_000_000}, {10, 1_000_000}, {20, 500_000}}; for (int[] c : customCases) { int B = c[0], R = c[1]; bench( String.format("B=%d binders by name, %,d requests", B, R), () -> benchCustomSlow(B, R), () -> benchCustomFast(B, R), (long) B * R, (long) R ); } System.out.println(); System.out.println("Defect : fiber/bind.go:391 — slices.Contains(customBinder.MIMETypes(), ctype)"); System.out.println(" fiber/bind.go:216 — for _, customBinder := range binders { if customBinder.Name() == name"); System.out.println("Fix : app.customBindersByMIME/customBindersByName maps — O(1) dispatch"); System.out.println("Ticket : fiber-0001-custom-binder-mime-slice-scan.md"); System.out.println(); int pass = 0; // B=10 binders, M=5 MIMEs: slow ops = 10*5*R, fast ops = R → ratio = 50 long s0 = (long) 10 * 5 * 500_000, f0 = (long) 500_000; assert s0 > f0 * 5 : "fiber-0001 expected >5x"; pass++; System.out.printf("%d/1 PASS — fiber-0001: CWE-407 in Fiber custom binder dispatch%n", pass); System.out.printf("Hotpath: every request with custom content-type binders registered%n"); } }