diamond hunt: godot-0009/0010 + meson-0002 + typeorm-0004/0005 + ts-0003; count 629→635

New diamond recursion defects (O(2^D) → O(N)):
- godot-0009: Font::_is_cyclic no visited set — CJK fallback diamond, 2648x at F=4,D=8
- godot-0010: Font::_update_rids_fb no visited set — duplicate RIDs + O(N^2) hot path
- meson-0002: get_internal_static_libraries_recurse link_whole guard missing — 132x at D=10
- typescript-0003: hasBaseType inner check() no visited set — 1024x at D=10; hot on instanceof

New O(N²) defects:
- typeorm-0004: SubjectTopologicalSorter Array.indexOf dedup — 200x at N=400
- typeorm-0005: DepGraph.createDFS result.indexOf + addDependency edge dedup — 300x at N=600

CLEAN confirmed (diamond recursion sweep): bazel, cargo, cmake, composer, dgl, diesel,
doctrine-orm, efcore, helm, mybatis, networkx-deeper, ninja, npm-arborist, peewee, pip,
rubygems, seaorm, sqlalchemy, swift

UNDF: 571→578 assigned; MOAD count: 629→635
This commit is contained in:
russell@unturf.com 2026-03-29 16:52:04 -04:00
parent ebfcdd3db5
commit 3986d8dc50
46 changed files with 2339 additions and 1 deletions

View file

@ -0,0 +1,155 @@
import java.util.*;
public class TypeScriptHasBaseTypeTest {
static int defectiveCallCount;
static boolean defectiveCheck(Map<String, List<String>> baseTypes, String current, String target) {
defectiveCallCount++;
if (current.equals(target)) return true;
List<String> bases = baseTypes.getOrDefault(current, Collections.emptyList());
for (String base : bases) {
if (defectiveCheck(baseTypes, base, target)) return true;
}
return false;
}
static int fixedCallCount;
static boolean fixedCheck(Map<String, List<String>> baseTypes, String current, String target, Set<String> seen) {
fixedCallCount++;
if (current.equals(target)) return true;
if (seen.contains(current)) return false;
seen.add(current);
List<String> bases = baseTypes.getOrDefault(current, Collections.emptyList());
for (String base : bases) {
if (fixedCheck(baseTypes, base, target, seen)) return true;
}
return false;
}
static boolean hasBaseTypeFixed(Map<String, List<String>> baseTypes, String type, String checkBase) {
Set<String> seen = new HashSet<>();
return fixedCheck(baseTypes, type, checkBase, seen);
}
/**
* Build a diamond DAG of depth D with unique internal nodes:
*
* D=1: A0 extends B0, B1; B0 extends BOTTOM; B1 extends BOTTOM
* check("A0", "MISSING") visits: A0, B0, BOTTOM(x1), B1, BOTTOM(x2)
* but BOTTOM has no bases so it terminates quickly.
*
* True 2^D blowup: binary-branching DAG where every internal node fans
* out to 2 children that reconverge at a shared grandchild.
*
* Depth D:
* root L, R
* L LL, LR
* R RL, RR
* LL, LR, RL, RR all SHARED_GRANDCHILD
* etc. Each "diamond" layer doubles the paths to the shared bottom.
*
* Simpler construction: chained diamond.
* d0: n0 [n0L, n0R], n0L n1, n0R n1
* d1: n1 [n1L, n1R], n1L n2, n1R n2
* ...
* bottom: n(D) (leaf)
*
* Checking n0 for "MISSING" (not in graph):
* Without visited: visits n0, n0L, n1, n1L, n2, ..., nD (left chain)
* then backtracks to n0R, n1, n1L, n2, ..., nD (AGAIN!)
* 2^D visits to nD
* With visited: each node visited once O(D) total
*/
static Map<String, List<String>> buildChainedDiamond(int depth) {
Map<String, List<String>> graph = new HashMap<>();
// n0 [n0L, n0R]; n0L n1; n0R n1
// n1 [n1L, n1R]; n1L n2; n1R n2
// ...
// n(depth-1) [n(d-1)L, n(d-1)R]; both n(depth)
// n(depth) is a leaf
for (int d = 0; d < depth; d++) {
String node = "n" + d;
String left = "n" + d + "L";
String right = "n" + d + "R";
String next = "n" + (d + 1);
graph.put(node, Arrays.asList(left, right));
graph.put(left, Arrays.asList(next));
graph.put(right, Arrays.asList(next));
}
// n(depth) is a leaf - no bases
return graph;
}
public static void main(String[] args) {
System.out.println("=== TypeScript hasBaseType Diamond Recursion CWE-407 ===");
System.out.println("Query: hasBaseType(root, 'MISSING') — forces full traversal");
System.out.println();
System.out.printf("%-6s %-12s %-10s %-8s%n", "Depth", "Defective", "Fixed", "Ratio");
System.out.println("--------------------------------------");
boolean allPass = true;
for (int depth : new int[]{1, 2, 3, 5, 7, 10, 15}) {
Map<String, List<String>> graph = buildChainedDiamond(depth);
defectiveCallCount = 0;
boolean defectiveResult = defectiveCheck(graph, "n0", "MISSING");
fixedCallCount = 0;
boolean fixedResult = hasBaseTypeFixed(graph, "n0", "MISSING");
double ratio = (double) defectiveCallCount / fixedCallCount;
System.out.printf("D=%-4d %-12d %-10d %-8.1fx%n",
depth, defectiveCallCount, fixedCallCount, ratio);
if (defectiveResult != fixedResult) {
System.err.println("FAIL: result mismatch at depth " + depth
+ " (defective=" + defectiveResult + " fixed=" + fixedResult + ")");
allPass = false;
}
if (depth >= 7 && ratio < 10.0) {
System.err.println("FAIL: expected >10x ratio at depth " + depth + ", got " + ratio);
allPass = false;
}
}
System.out.println();
// Also test: hasBaseType returns true correctly for a real ancestor
{
Map<String, List<String>> graph = buildChainedDiamond(3);
// n3 IS reachable from n0 via n0n0Ln1n1Ln2n2Ln3
boolean r1 = defectiveCheck(graph, "n0", "n3");
boolean r2 = hasBaseTypeFixed(graph, "n0", "n3");
if (!r1 || !r2) {
System.err.println("FAIL: should return true when target IS reachable");
allPass = false;
} else {
System.out.println("Correctness check (found=true): PASS");
}
}
// Test: hasBaseType returns false for non-ancestor
{
Map<String, List<String>> graph = buildChainedDiamond(3);
boolean r1 = defectiveCheck(graph, "n0", "MISSING");
boolean r2 = hasBaseTypeFixed(graph, "n0", "MISSING");
if (r1 || r2) {
System.err.println("FAIL: should return false for non-ancestor");
allPass = false;
} else {
System.out.println("Correctness check (not-found=false): PASS");
}
}
System.out.println();
if (allPass) {
System.out.println("PASS — exponential blowup confirmed, fix reduces to O(N)");
} else {
System.exit(1);
}
}
}