#!/usr/bin/env bash # Regression harness for issue-create.sh Markdown-body safety (#559). # # Guards against reintroduction of eval-based command construction. The wrapper # builds its tea/gh invocation as an argv array, so a body containing command # substitution ($(...)), backticks, quotes, and dollar signs MUST reach tea # verbatim and MUST NOT be shell-evaluated. This test asserts both: # 1. No command-substitution side effect (an injected `touch SENTINEL` never runs). # 2. The --description value tea receives is byte-for-byte the original body. set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" WORK_DIR="${MOSAIC_TEST_WORK_DIR:-$PWD/.mosaic-test-work/issue-create-body-safety}" REPO_DIR="$WORK_DIR/repo" BIN_DIR="$WORK_DIR/bin" SENTINEL="$WORK_DIR/INJECTION_SENTINEL" BODY_FILE="$WORK_DIR/body.txt" RECEIVED_FILE="$WORK_DIR/received-description.txt" rm -rf "$WORK_DIR" mkdir -p "$REPO_DIR" "$BIN_DIR" git -C "$REPO_DIR" init -q git -C "$REPO_DIR" remote add origin https://git.mosaicstack.dev/mosaicstack/stack.git # Hostile Markdown body. The unquoted heredoc expands $SENTINEL (a real path we # want embedded) but every shell metacharacter we care about is backslash-escaped # so the TEST shell writes them literally into the file — the bytes the wrapper # must then preserve. cat > "$BODY_FILE" < "$BIN_DIR/tea" <<'SH' #!/usr/bin/env bash set -euo pipefail if [[ "$*" == "login list --output json" ]]; then cat <<'JSON' [ {"name":"mosaicstack","url":"https://git.mosaicstack.dev","user":"jason.woltje"} ] JSON exit 0 fi if [[ "${1:-}" == "issue" && "${2:-}" == "create" ]]; then desc="" while [[ $# -gt 0 ]]; do case "$1" in --description) desc="$2"; shift 2 ;; *) shift ;; esac done printf '%s' "$desc" > "$MOSAIC_TEST_RECEIVED" echo "#1 created" exit 0 fi exit 0 SH chmod +x "$BIN_DIR/tea" ( cd "$REPO_DIR" PATH="$BIN_DIR:$PATH" \ MOSAIC_TEST_RECEIVED="$RECEIVED_FILE" \ "$SCRIPT_DIR/issue-create.sh" -t "Body safety test" -b "$BODY" ) >/dev/null # 1. No command substitution executed anywhere in the pipeline. if [[ -e "$SENTINEL" ]]; then echo "FAIL: injected command substitution executed (sentinel file created): $SENTINEL" >&2 exit 1 fi # 2. tea actually received the body (issue create path taken, not silently dropped). if [[ ! -f "$RECEIVED_FILE" ]]; then echo "FAIL: tea issue create was never invoked with a --description" >&2 exit 1 fi # 3. The description tea received is byte-for-byte the original body. if [[ "$(cat "$RECEIVED_FILE")" != "$BODY" ]]; then echo "FAIL: body was not preserved verbatim through issue-create.sh" >&2 echo "--- expected ---" >&2; printf '%s\n' "$BODY" >&2 echo "--- received ---" >&2; cat "$RECEIVED_FILE" >&2 exit 1 fi echo "issue-create.sh Markdown body-safety regression harness passed"