java-topology/defects/postgres/unit/PostgresTest.java
russell@unturf.com ff6292d067 wave17: postgres-0001/asterisk-0001/haproxy-0001/nginx-0001; postfix+bevy CLEAN
postgres-0001: pg_inherits.c typeInheritsFrom() BFS visited List → HTAB O(1)
asterisk-0001: app_queue.c interface_exists() ao2_iterator walk → ao2_find O(1)
haproxy-0001: http_ana.c cookie-server scan linked-list → eb-tree index O(log S)
nginx-0001: ngx_http_link_multi_headers() O(H²) double-scan → O(H) hash pass
postfix: CLEAN (htable throughout; two marginal LOW admin-bounded candidates)
bevy: CLEAN (FixedBitSet/HashSet throughout; only hardware-bounded marginals)
2026-03-30 07:57:30 -04:00

113 lines
4.4 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import java.util.*;
/**
* CWE-407 unit test for PostgreSQL pg_inherits.c defect.
*
* postgres-0001: src/backend/catalog/pg_inherits.c typeInheritsFrom()
* BFS over pg_inherits using List *visited + list_member_oid() — O(V) per node,
* O(V²) total for a deep/wide hierarchy.
* Fix: replace List *visited with HTAB *visited_set (same pattern as
* find_all_inheritors in the same file) for O(1) per-node visited check.
*/
public class PostgresTest {
// Simulate defect: List visited + linear scan
static boolean typeInheritsFrom_list(int[][] parentEdges, int subclass, int superclass) {
// parentEdges[i] = {child_oid, parent_oid}
// BFS from subclass upward; visited is a list (O(V) scan per entry)
List<Integer> queue = new ArrayList<>();
List<Integer> visited = new ArrayList<>();
queue.add(subclass);
int head = 0;
while (head < queue.size()) {
int current = queue.get(head++);
boolean alreadySeen = false;
for (int v : visited) { // O(V) — defect
if (v == current) { alreadySeen = true; break; }
}
if (alreadySeen) continue;
visited.add(current);
for (int[] edge : parentEdges) {
if (edge[0] == current) {
int parent = edge[1];
if (parent == superclass) return true;
queue.add(parent);
}
}
}
return false;
}
// Simulate fix: HashSet visited
static boolean typeInheritsFrom_htab(int[][] parentEdges, int subclass, int superclass) {
List<Integer> queue = new ArrayList<>();
Set<Integer> visited = new HashSet<>(); // O(1) lookup
queue.add(subclass);
int head = 0;
while (head < queue.size()) {
int current = queue.get(head++);
if (!visited.add(current)) continue; // O(1)
for (int[] edge : parentEdges) {
if (edge[0] == current) {
int parent = edge[1];
if (parent == superclass) return true;
queue.add(parent);
}
}
}
return false;
}
static void testPostgres0001() throws Exception {
// Build a diamond-inheritance graph: V types in a chain with cross-links
// Use the negative case (not found) — forces full BFS traversal of all V nodes,
// maximising the visited-list size reached during each member check.
int V = 800;
// All-to-all fan-out: node i has edges to i+1..i+10 (wide BFS tree)
List<int[]> edges = new ArrayList<>();
for (int i = 0; i < V; i++) {
for (int k = 1; k <= 10 && i + k < V; k++) {
edges.add(new int[]{i, i + k});
}
}
int[][] parentEdges = edges.toArray(new int[0][]);
int subclass = 0;
int superclass = V - 1; // reachable (positive case)
int missing = 999999; // not reachable (negative case — full traversal)
// correctness
boolean r1 = typeInheritsFrom_list(parentEdges, subclass, superclass);
boolean r2 = typeInheritsFrom_htab(parentEdges, subclass, superclass);
assert r1 == r2 : "list and htab must agree (positive): " + r1 + " vs " + r2;
boolean n1 = typeInheritsFrom_list(parentEdges, subclass, missing);
boolean n2 = typeInheritsFrom_htab(parentEdges, subclass, missing);
assert n1 == n2 && !n1 : "negative case must agree";
// performance on negative case: forces complete traversal, visited grows to V
int REPS = 100;
long t0 = System.nanoTime();
for (int r = 0; r < REPS; r++) typeInheritsFrom_list(parentEdges, subclass, missing);
long tList = System.nanoTime() - t0;
t0 = System.nanoTime();
for (int r = 0; r < REPS; r++) typeInheritsFrom_htab(parentEdges, subclass, missing);
long tHash = System.nanoTime() - t0;
double ratio = (double) tList / tHash;
System.out.printf("postgres-0001: list=%.3fs htab=%.3fs ratio=%.1f×%n",
tList / 1e9, tHash / 1e9, ratio);
assert ratio > 1.2 : "Expected >1.2× speedup, got " + ratio;
System.out.println("PASS postgres-0001");
}
public static void main(String[] args) throws Exception {
testPostgres0001();
System.out.println("ALL PASS");
}
}