Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## Unreleased

### Fixed
- `bashunit learn` and coverage now create temp directories via `mktemp -d` (no predictable PID-based paths under `/tmp`)
- `bashunit::parallel::cleanup` refuses to `rm -rf` a `TEMP_DIR_PARALLEL_TEST_SUITE` whose path is not under `*/bashunit/parallel/*`, preventing accidental wipes from env overrides

### Internal
- Codify global-slot return pattern for hot-path helpers; namespace mock/spy state under `_BASHUNIT_SPY_*` (#674)

Expand Down
7 changes: 3 additions & 4 deletions src/coverage.sh
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,10 @@ function bashunit::coverage::init() {
return 0
fi

# Create coverage data directory with unique name
# Use $$ (PID) + $RANDOM to avoid conflicts when tests call coverage::init
# Create coverage data directory with unique name via mktemp -d
# (avoids $$-$RANDOM collisions and symlink races in shared temp dirs)
local coverage_dir
coverage_dir="${BASHUNIT_TEMP_DIR:-/tmp}/bashunit-coverage-$$-$RANDOM"
mkdir -p "$coverage_dir"
coverage_dir=$("${MKTEMP:-mktemp}" -d "${BASHUNIT_TEMP_DIR:-${TMPDIR:-/tmp}}/bashunit-coverage.XXXXXXXX")

_BASHUNIT_COVERAGE_DATA_FILE="${coverage_dir}/hits.dat"
_BASHUNIT_COVERAGE_TRACKED_FILES="${coverage_dir}/files.dat"
Expand Down
8 changes: 5 additions & 3 deletions src/learn.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,24 @@
# Provides guided tutorials and exercises to learn bashunit
##

declare -r LEARN_TEMP_DIR="/tmp/bashunit_learn_$$"
LEARN_TEMP_DIR=""
declare -r LEARN_PROGRESS_FILE="$HOME/.bashunit_learn_progress"

##
# Initialize learning environment
##
function bashunit::learn::init() {
mkdir -p "$LEARN_TEMP_DIR"
LEARN_TEMP_DIR=$("${MKTEMP:-mktemp}" -d "${TMPDIR:-/tmp}/bashunit_learn.XXXXXXXX")
mkdir -p tests
}

##
# Cleanup learning environment
##
function bashunit::learn::cleanup() {
rm -rf "$LEARN_TEMP_DIR"
if [ -n "${LEARN_TEMP_DIR:-}" ] && [ -d "$LEARN_TEMP_DIR" ]; then
rm -rf "$LEARN_TEMP_DIR"
fi
}

##
Expand Down
11 changes: 10 additions & 1 deletion src/parallel.sh
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,16 @@ function bashunit::parallel::must_stop_on_failure() {

function bashunit::parallel::cleanup() {
# shellcheck disable=SC2153
rm -rf "$TEMP_DIR_PARALLEL_TEST_SUITE"
local target="$TEMP_DIR_PARALLEL_TEST_SUITE"
case "$target" in
*/bashunit/parallel/*)
rm -rf "$target"
;;
*)
bashunit::internal_log "parallel::cleanup" "refused unsafe path:$target"
return 1
;;
esac
}

function bashunit::parallel::init() {
Expand Down
14 changes: 13 additions & 1 deletion tests/unit/parallel_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ function set_up() {
_ORIGINAL_TEMP_DIR_PARALLEL="${TEMP_DIR_PARALLEL_TEST_SUITE:-}"
_ORIGINAL_TEMP_FILE_STOP="${TEMP_FILE_PARALLEL_STOP_ON_FAILURE:-}"

export TEMP_DIR_PARALLEL_TEST_SUITE="$_TEST_TEMP_DIR/parallel_suite"
export TEMP_DIR_PARALLEL_TEST_SUITE="$_TEST_TEMP_DIR/bashunit/parallel/suite"
export TEMP_FILE_PARALLEL_STOP_ON_FAILURE="$_TEST_TEMP_DIR/stop_on_failure"
}

Expand Down Expand Up @@ -147,6 +147,18 @@ function test_cleanup_removes_temp_directory() {
assert_directory_not_exists "$TEMP_DIR_PARALLEL_TEST_SUITE"
}

function test_cleanup_refuses_path_outside_bashunit_parallel() {
local unsafe_dir="$_TEST_TEMP_DIR/not_bashunit"
mkdir -p "$unsafe_dir"
export TEMP_DIR_PARALLEL_TEST_SUITE="$unsafe_dir"

local rc=0
bashunit::parallel::cleanup || rc=$?

assert_same "1" "$rc"
assert_directory_exists "$unsafe_dir"
}

# === stop_on_failure tests ===

function test_mark_stop_on_failure_creates_file() {
Expand Down
Loading