java-topology/defects/ktor/unit/KtorTest.java

154 lines
7 KiB
Java

package unit;
import java.util.*;
/**
* KtorTest — CWE-407 scan result: CLEAN
*
* Ktor server-core and plugins were scanned for CWE-407 (O(n) membership tests
* inside loops). No confirmed defects found. This file documents the scan and
* validates that the clean patterns are indeed O(1).
*
* Key verified locations:
* - BaseApplicationRequest.kt:65,69 — removed: mutableSetOf<String>() — O(1)
* - ResponseHeaders.kt:63 — managedByEngineHeaders: Set<String> — O(1)
* - StaticContentResolution.kt:150 — one-shot safety check, not in loop
* - EmbeddedServerJvm.kt:468 — startup-only, ArrayList(1) capacity
* - CORSUtils.kt:104 — allHeadersSet: Set<String> (toSet()) — O(1)
* - CORSConfig.kt:44,57 — CaseInsensitiveSet (Set impl) — O(1)
* - CallId.kt:276 — dictionarySet: Set<Char> — O(1)
*
* This benchmark validates that the Set-based patterns Ktor already uses are
* genuinely faster than List-based alternatives, confirming the defect is absent.
*/
public class KtorTest {
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 = fMs > 0 ? (double) sMs / fMs : 0;
System.out.printf(" %-52s slow:%4dms (%,d ops) fast:%4dms (%,d ops) speedup:%.1fx%n",
label, sMs, sOps, fMs, fOps, r);
}
// -----------------------------------------------------------------------
// Validate: CORSUtils corsCheckRequestHeaders
// requestHeaders (List) iterated; membership check against allHeadersSet.
// Ktor uses Set (correct). Benchmark confirms Set > List here.
// -----------------------------------------------------------------------
static boolean corsCheckSlow(List<String> requestHeaders, List<String> allHeadersList) {
for (String header : requestHeaders) {
if (!allHeadersList.contains(header)) return false; // O(n) per header — hypothetical slow
}
return true;
}
static boolean corsCheckFast(List<String> requestHeaders, Set<String> allHeadersSet) {
for (String header : requestHeaders) {
if (!allHeadersSet.contains(header)) return false; // O(1) — what Ktor actually does
}
return true;
}
// -----------------------------------------------------------------------
// Validate: ResponseHeaders managedByEngineHeaders
// Ktor uses Set<String>. Confirm correctness.
// -----------------------------------------------------------------------
static boolean headerManagedSlow(String name, List<String> managedList) {
return managedList.contains(name); // O(n) — hypothetical
}
static boolean headerManagedFast(String name, Set<String> managedSet) {
return managedSet.contains(name); // O(1) — what Ktor actually does
}
// -----------------------------------------------------------------------
// Validate: CallId verifyCallIdAgainstDictionary
// Ktor uses Set<Char>. Confirm correctness.
// -----------------------------------------------------------------------
static boolean verifyCallIdSlow(String callId, List<Character> dict) {
for (char c : callId.toCharArray()) {
if (!dict.contains(c)) return false; // O(n) — hypothetical
}
return true;
}
static boolean verifyCallIdFast(String callId, Set<Character> dict) {
for (char c : callId.toCharArray()) {
if (!dict.contains(c)) return false; // O(1) — what Ktor actually does
}
return true;
}
public static void main(String[] args) {
System.out.println("Ktor CWE-407 Scan — CLEAN (validation benchmarks)");
System.out.println("==================================================");
System.out.println("Ktor uses Set-based structures for all hot-path membership tests.");
System.out.println("Benchmarks below confirm Set is faster, validating the absence of defects.");
System.out.println();
int ITERS = 2_000_000;
// --- CORS header check ---
String[] headerNames = {"content-type", "authorization", "x-custom-header",
"accept", "origin", "x-request-id"};
List<String> allHeadersList = Arrays.asList(headerNames);
Set<String> allHeadersSet = new HashSet<>(Arrays.asList(headerNames));
List<String> requestHeaders = Arrays.asList("content-type", "authorization", "accept");
System.out.println("CORSUtils corsCheckRequestHeaders (Ktor: Set — CLEAN)");
bench(
"CORS header check: List.contains vs Set.contains (H=6)",
() -> { for (int i = 0; i < ITERS; i++) corsCheckSlow(requestHeaders, allHeadersList); },
() -> { for (int i = 0; i < ITERS; i++) corsCheckFast(requestHeaders, allHeadersSet); },
ITERS, ITERS
);
// --- managedByEngineHeaders ---
// Ktor Tomcat: {TransferEncoding, Connection} — tiny set
List<String> managedList = Arrays.asList("Transfer-Encoding", "Connection");
Set<String> managedSet = new HashSet<>(managedList);
// Worst case: checking a header not in the set
String notManaged = "Content-Type";
System.out.println();
System.out.println("ResponseHeaders managedByEngineHeaders (Ktor: Set — CLEAN)");
bench(
"managedByEngineHeaders: List.contains vs Set.contains (H=2)",
() -> { for (int i = 0; i < ITERS; i++) headerManagedSlow(notManaged, managedList); },
() -> { for (int i = 0; i < ITERS; i++) headerManagedFast(notManaged, managedSet); },
ITERS, ITERS
);
// --- CallId dictionary validation ---
// Typical dictionary: alphanumeric + hyphens (62+ chars)
String dictStr = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-";
List<Character> dictList = new ArrayList<>();
Set<Character> dictSet = new HashSet<>();
for (char c : dictStr.toCharArray()) { dictList.add(c); dictSet.add(c); }
// 32-char UUID-style call ID
String callId = "550e8400-e29b-41d4-a716-446655440000";
System.out.println();
System.out.println("CallId verifyCallIdAgainstDictionary (Ktor: Set<Char> — CLEAN)");
bench(
"callId verify: List<Char>.contains vs Set<Char>.contains (D=63)",
() -> { for (int i = 0; i < ITERS / 10; i++) verifyCallIdSlow(callId, dictList); },
() -> { for (int i = 0; i < ITERS / 10; i++) verifyCallIdFast(callId, dictSet); },
ITERS / 10, ITERS / 10
);
System.out.println();
System.out.println("Verdict: Ktor is CLEAN. All membership tests use Set-based O(1) structures.");
System.out.println("Done.");
}
}