#!/usr/bin/env bash # CWE-407 scan — PostgreSQL query planner and executor # PostgreSQL uses its own list API: list_member(), foreach()/lfirst(), lappend() # Strategy: lead with pg-specific O(n) membership calls, check ±20 lines for loop context. set -euo pipefail echo "# scan=postgresql host=$(hostname) date=$(date -u +%Y-%m-%dT%H:%M:%SZ)" cd /tmp && git clone --depth 1 https://github.com/postgres/postgres postgres 2>&1 | tail -1 # O(n) membership patterns in PostgreSQL's list API PG_MEM='list_member\b|list_member_ptr\b|list_member_int\b|list_member_oid\b|list_member_xid\b' # Loop constructs that would make the above O(n²) PG_LOOP='foreach\b|for\s*\(.*List\|while\s*\(.*List\|do\s*{.*List' for dir in \ src/backend/optimizer \ src/backend/nodes \ src/backend/rewrite \ src/backend/executor \ src/backend/parser \ src/backend/planner; do [ -d /tmp/postgres/$dir ] || continue echo "# roots: /tmp/postgres/$dir" find /tmp/postgres/$dir -name "*.c" -o -name "*.h" 2>/dev/null | sort | while IFS= read -r f; do # Find all list_member* call sites ml=$(grep -nE "$PG_MEM" "$f" 2>/dev/null | cut -d: -f1 || true) [ -z "$ml" ] && continue while IFS= read -r ln; do s=$(( ln > 20 ? ln - 20 : 1 )); e=$(( ln + 20 )) ctx=$(sed -n "${s},${e}p" "$f" 2>/dev/null || true) # Emit candidate if a loop construct appears in the same ±20-line window loop_hit=$(echo "$ctx" | grep -iE "$PG_LOOP" | head -1 | sed 's/^\s*//' || true) [ -n "$loop_hit" ] && { mem_line=$(sed -n "${ln}p" "$f" | sed 's/^\s*//') echo "CANDIDATE ${f}:${ln} ${mem_line} [loop: ${loop_hit}]" } done <<< "$ml" done done echo "# scan complete"