mirror of
https://github.com/DeusData/codebase-memory-mcp.git
synced 2026-10-28 07:03:20 +08:00
Route MCP existence-only probes through existing CBM file and directory helpers instead of raw access/stat checks. Reuse project_db_path for QN cold-start DB lookup, length-check ADR probes, and keep metadata-dependent stat calls unchanged. Extend source-safety to block newly added raw access() and strndup() in production diffs, with self-tests for both guard paths. Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
130 lines
4.6 KiB
Bash
130 lines
4.6 KiB
Bash
#!/usr/bin/env bash
|
|
# test-source-safety.sh — self-tests for scripts/check-source-safety.sh.
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
TMP_PARENT="${TMPDIR:-/tmp}"
|
|
TMP_ROOT="$(mktemp -d "$TMP_PARENT/cbm-source-safety-test-XXXXXX")"
|
|
|
|
cleanup() {
|
|
rm -rf "$TMP_ROOT"
|
|
}
|
|
trap cleanup EXIT
|
|
|
|
make_tree() {
|
|
local root="$1"
|
|
mkdir -p "$root/src/mcp" "$root/src/pipeline" "$root/src/graph_buffer" \
|
|
"$root/src/semantic" "$root/internal/cbm" "$root/cmd"
|
|
}
|
|
|
|
run_guard() {
|
|
local root="$1"
|
|
local log="$2"
|
|
CBM_SOURCE_SAFETY_ROOT="$root" bash "$REPO_ROOT/scripts/check-source-safety.sh" \
|
|
>"$log" 2>&1
|
|
}
|
|
|
|
expect_pass() {
|
|
local name="$1"
|
|
local root="$2"
|
|
local log="$TMP_ROOT/$name.log"
|
|
if ! run_guard "$root" "$log"; then
|
|
echo "[source-safety-test] expected pass failed: $name"
|
|
cat "$log"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
expect_fail_contains() {
|
|
local name="$1"
|
|
local root="$2"
|
|
local needle="$3"
|
|
local log="$TMP_ROOT/$name.log"
|
|
if run_guard "$root" "$log"; then
|
|
echo "[source-safety-test] expected failure passed unexpectedly: $name"
|
|
cat "$log"
|
|
exit 1
|
|
fi
|
|
if ! grep -q "$needle" "$log"; then
|
|
echo "[source-safety-test] expected '$needle' in $name output"
|
|
cat "$log"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
clean_root="$TMP_ROOT/clean"
|
|
make_tree "$clean_root"
|
|
printf 'void ok(void) {}\n' >"$clean_root/src/mcp/ok.c"
|
|
expect_pass "clean" "$clean_root"
|
|
|
|
stdout_root="$TMP_ROOT/stdout"
|
|
make_tree "$stdout_root"
|
|
printf '#include <stdio.h>\nvoid bad(void) { printf("bad\\n"); }\n' \
|
|
>"$stdout_root/src/mcp/bad.c"
|
|
expect_fail_contains "stdout" "$stdout_root" "stdout write"
|
|
|
|
fprintf_stdout_root="$TMP_ROOT/fprintf_stdout"
|
|
make_tree "$fprintf_stdout_root"
|
|
printf '#include <stdio.h>\nvoid bad(void) { fprintf(stdout, "bad\\n"); }\n' \
|
|
>"$fprintf_stdout_root/src/pipeline/bad.c"
|
|
expect_fail_contains "fprintf_stdout" "$fprintf_stdout_root" "stdout write"
|
|
|
|
string_root="$TMP_ROOT/string"
|
|
make_tree "$string_root"
|
|
printf '#include <string.h>\nvoid bad(char *d, const char *s) { strcpy(d, s); }\n' \
|
|
>"$string_root/src/pipeline/bad.c"
|
|
expect_fail_contains "unsafe_string" "$string_root" "unsafe string API"
|
|
|
|
strncpy_root="$TMP_ROOT/strncpy"
|
|
make_tree "$strncpy_root"
|
|
printf '#include <string.h>\nvoid bad(char *d, const char *s) { strncpy(d, s, 3); }\n' \
|
|
>"$strncpy_root/src/pipeline/bad.c"
|
|
expect_fail_contains "unsafe_strncpy" "$strncpy_root" "unsafe string API"
|
|
|
|
rawfs_root="$TMP_ROOT/rawfs"
|
|
make_tree "$rawfs_root"
|
|
git -C "$rawfs_root" init -q
|
|
git -C "$rawfs_root" config user.email source-safety@example.invalid
|
|
git -C "$rawfs_root" config user.name source-safety
|
|
printf 'void ok(void) {}\n' >"$rawfs_root/src/pipeline/ok.c"
|
|
git -C "$rawfs_root" add src/pipeline/ok.c
|
|
git -C "$rawfs_root" commit -qm init
|
|
printf 'void bad(void) { unlink("x"); }\n' >>"$rawfs_root/src/pipeline/ok.c"
|
|
expect_fail_contains "raw_fs_diff" "$rawfs_root" "new raw env/fs API"
|
|
|
|
rawaccess_root="$TMP_ROOT/rawaccess"
|
|
make_tree "$rawaccess_root"
|
|
git -C "$rawaccess_root" init -q
|
|
git -C "$rawaccess_root" config user.email source-safety@example.invalid
|
|
git -C "$rawaccess_root" config user.name source-safety
|
|
printf 'void ok(void) {}\n' >"$rawaccess_root/src/pipeline/ok.c"
|
|
git -C "$rawaccess_root" add src/pipeline/ok.c
|
|
git -C "$rawaccess_root" commit -qm init
|
|
printf 'int bad(const char *s) { return access(s, 0); }\n' >>"$rawaccess_root/src/pipeline/ok.c"
|
|
expect_fail_contains "raw_access_diff" "$rawaccess_root" "new raw env/fs API"
|
|
|
|
rawdup_root="$TMP_ROOT/rawdup"
|
|
make_tree "$rawdup_root"
|
|
git -C "$rawdup_root" init -q
|
|
git -C "$rawdup_root" config user.email source-safety@example.invalid
|
|
git -C "$rawdup_root" config user.name source-safety
|
|
printf 'void ok(void) {}\n' >"$rawdup_root/src/pipeline/ok.c"
|
|
git -C "$rawdup_root" add src/pipeline/ok.c
|
|
git -C "$rawdup_root" commit -qm init
|
|
printf 'char *bad(const char *s) { return strdup(s); }\n' >>"$rawdup_root/src/pipeline/ok.c"
|
|
expect_fail_contains "raw_strdup_diff" "$rawdup_root" "new raw strdup"
|
|
|
|
rawstrndup_root="$TMP_ROOT/rawstrndup"
|
|
make_tree "$rawstrndup_root"
|
|
git -C "$rawstrndup_root" init -q
|
|
git -C "$rawstrndup_root" config user.email source-safety@example.invalid
|
|
git -C "$rawstrndup_root" config user.name source-safety
|
|
printf 'void ok(void) {}\n' >"$rawstrndup_root/src/pipeline/ok.c"
|
|
git -C "$rawstrndup_root" add src/pipeline/ok.c
|
|
git -C "$rawstrndup_root" commit -qm init
|
|
printf 'char *bad(const char *s) { return strndup(s, 3); }\n' >>"$rawstrndup_root/src/pipeline/ok.c"
|
|
expect_fail_contains "raw_strndup_diff" "$rawstrndup_root" "new raw strdup/strndup"
|
|
|
|
echo "[source-safety-test] OK"
|