java-topology/tools/scans/sqlite.sh
russell@unturf.com db29a08762 undefect. CWE-407 — 92 sites, 42 ecosystems
B&W print-friendly diagrams + tinkerpop-0001 + wave-3 proof sections.
Squash of 94 local commits onto remote master.
2026-03-26 19:48:18 -04:00

58 lines
2.4 KiB
Bash
Executable file

#!/usr/bin/env bash
# CWE-407 scan — SQLite query planner and optimizer
# SQLite uses array-backed list types: ExprList, SrcList, IdList
# Membership via linear loops: for(i=0; i<pList->n; i++) + equality
# Strategy: lead with known O(n) scan patterns, check ±20 lines for outer loop.
set -euo pipefail
echo "# scan=sqlite host=$(hostname) date=$(date -u +%Y-%m-%dT%H:%M:%SZ)"
cd /tmp && git clone --depth 1 https://github.com/sqlite/sqlite sqlite 2>&1 | tail -1
# O(n) membership patterns: linear scans over SQLite list types
# - sqlite3ExprListFind: linear scan returning index
# - loops over nExpr/nSrc/nId with equality/comparison inside
SQ_MEM='sqlite3ExprListFind\b|sqlite3IdListIndex\b|for\s*\(.*->nExpr\b|for\s*\(.*->nSrc\b|for\s*\(.*->nId\b|while\s*\(.*->nExpr\b'
# Outer loop constructs that would make the above O(n²)
# Include both for-loop over list fields and recursive traversal
SQ_LOOP='for\s*\(.*pList\|for\s*\(.*pExpr\|for\s*\(.*pSrc\|for\s*\(.*->a\[|while\s*\(.*->a\[|sqlite3WalkExprList\b|sqlite3WalkSelectExpr\b'
for dir in \
src \
tool; do
[ -d /tmp/sqlite/$dir ] || continue
echo "# roots: /tmp/sqlite/$dir"
find /tmp/sqlite/$dir -name "*.c" -o -name "*.h" 2>/dev/null | sort | while IFS= read -r f; do
ml=$(grep -nE "$SQ_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)
loop_hit=$(echo "$ctx" | grep -iE "$SQ_LOOP" | head -1 | sed 's/^\s*//' || true)
[ -n "$loop_hit" ] && {
mem_line=$(sed -n "${ln}p" "$f" | sed 's/^\s*//')
echo "CANDIDATE\t${f}:${ln}\t${mem_line} [loop: ${loop_hit}]"
}
done <<< "$ml"
done
done
# Also scan the amalgamation for patterns missed in src/
# (some logic only exists in sqlite3.c after preprocessing)
echo "# roots: /tmp/sqlite/sqlite3.c (amalgamation)"
f=/tmp/sqlite/sqlite3.c
if [ -f "$f" ]; then
ml=$(grep -nE "$SQ_MEM" "$f" 2>/dev/null | cut -d: -f1 || true)
while IFS= read -r ln; do
[ -z "$ln" ] && continue
s=$(( ln > 20 ? ln - 20 : 1 )); e=$(( ln + 20 ))
ctx=$(sed -n "${s},${e}p" "$f" 2>/dev/null || true)
loop_hit=$(echo "$ctx" | grep -iE "$SQ_LOOP" | head -1 | sed 's/^\s*//' || true)
[ -n "$loop_hit" ] && {
mem_line=$(sed -n "${ln}p" "$f" | sed 's/^\s*//')
echo "CANDIDATE\t${f}:${ln}\t${mem_line} [loop: ${loop_hit}]"
}
done <<< "$ml"
fi
echo "# scan complete"