ci/woodpecker/pr/ci Pipeline was canceled
be-coder-07 (#1089 review 131) showed the precondition guard exited 0 when the scratch dir turned out to be inside a git worktree: ( cd "$TMP" && git rev-parse --git-dir ) && { echo "SKIP"; exit 0; } so pointing TMPDIR beneath a git worktree made this test PASS against unchanged main. A skip that exits 0 is indistinguishable from a pass -- the same defect this suite exists to catch, in the suite itself. Now: set GIT_CEILING_DIRECTORIES to the PHYSICAL path (it is matched physically, and /tmp is commonly a symlink, so a logical path silently disables the ceiling), and if the outside-a-repo precondition still cannot be established, FAIL with an explicit message rather than skipping. Replaying be-coder-07's attack (TMPDIR beneath a worktree): before: fix rc=0, main rc=0 <- both "pass", the vulnerability after: fix rc=1, main rc=1 <- both refuse; no false pass either way Normal conditions are unchanged and still discriminate: fix rc=0, main rc=1. The test refuses to report a result it cannot establish. That is weaker than running under a hostile TMPDIR and strictly better than lying about it. Reported-by: be-coder-07
59 lines
3.2 KiB
Bash
Executable File
59 lines
3.2 KiB
Bash
Executable File
#!/bin/bash
|
|
# Regression: detect_platform / get_repo_info must FAIL LOUDLY outside a git repo,
|
|
# not kill the caller silently.
|
|
#
|
|
# Both functions already contained the right error path:
|
|
# if [[ -z "$remote_url" ]]; then echo "error: not a git repository..." >&2; return 1; fi
|
|
# but under `set -e` -- which every wrapper in this directory uses -- the preceding
|
|
# assignment `remote_url=$(git remote get-url origin 2>/dev/null)` returns git's 128
|
|
# outside a repo and terminates the CALLER first. The message was unreachable.
|
|
#
|
|
# Observed cost: pr-review.sh invoked from a non-repo cwd exits 128 with NO stdout and
|
|
# NO stderr, even when -r/--repo and -H/--host are supplied -- the flags documented as
|
|
# "skips git-remote inference". Two reviewer seats hit this and correctly reported
|
|
# `blocked` with no diagnostic to report.
|
|
#
|
|
# The control that matters is the LOUD one: asserting "rc != 0" passes on the broken
|
|
# build too, because 128 is also non-zero. The test must assert the MESSAGE.
|
|
set -uo pipefail
|
|
fail=0
|
|
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
TMP="$(mktemp -d)"; trap 'rm -rf "$TMP"' EXIT
|
|
|
|
run_outside() { # $1=function name -> "rc:sawmessage"
|
|
local fn="$1" out rc
|
|
out=$( cd "$TMP" && bash -c "set -e; source '$HERE/detect-platform.sh'; $fn" 2>&1 ); rc=$?
|
|
printf '%s:%s' "$rc" "$(grep -qi 'not a git repository' <<<"$out" && echo yes || echo no)"
|
|
}
|
|
check() { if [ "$2" = "$3" ]; then echo " PASS $1 ($2)"; else echo " FAIL $1: got $2, want $3"; fail=1; fi; }
|
|
|
|
# $TMP must not be inside a git repo. Do not SKIP on failure: be-coder-07 showed the
|
|
# original SKIP exited 0, so pointing TMPDIR beneath a git worktree made this test PASS
|
|
# against unchanged main. A skip that exits 0 is indistinguishable from a pass.
|
|
# GIT_CEILING_DIRECTORIES stops git walking above $TMP, making the condition hold
|
|
# regardless of where TMPDIR lives, rather than merely detecting when it does not.
|
|
# GIT_CEILING_DIRECTORIES is matched against the PHYSICAL path -- a symlinked TMPDIR
|
|
# (/tmp is commonly one) makes the logical path never match, and the ceiling silently
|
|
# does nothing. Resolve it before exporting.
|
|
TMP="$(cd "$TMP" && pwd -P)"
|
|
export GIT_CEILING_DIRECTORIES="$TMP"
|
|
if ( cd "$TMP" && git rev-parse --git-dir >/dev/null 2>&1 ); then
|
|
echo " FAIL scratch dir is inside a git repo even with GIT_CEILING_DIRECTORIES set;"
|
|
echo " the outside-a-repo precondition cannot be established -- refusing to report a result"
|
|
exit 1
|
|
fi
|
|
|
|
echo "== outside a git repo: rc=1 AND the diagnostic is emitted =="
|
|
check "detect_platform" "$(run_outside detect_platform)" "1:yes"
|
|
check "get_repo_info" "$(run_outside get_repo_info)" "1:yes"
|
|
|
|
echo "== inside a git repo the functions still work =="
|
|
git init -q "$TMP/repo" 2>/dev/null
|
|
git -C "$TMP/repo" remote add origin https://git.mosaicstack.dev/mosaicstack/stack.git 2>/dev/null
|
|
out=$( cd "$TMP/repo" && bash -c "set -e; source '$HERE/detect-platform.sh'; detect_platform" 2>&1 ); rc=$?
|
|
if [ "$rc" -eq 0 ] && grep -qi 'gitea' <<<"$out"; then echo " PASS detect_platform in-repo (rc=0, $out)"
|
|
else echo " FAIL detect_platform in-repo: rc=$rc out=$out"; fail=1; fi
|
|
|
|
[ "$fail" -eq 0 ] && echo "OK detect-platform fails loudly outside a repo" || echo "FAILED"
|
|
exit "$fail"
|