From f812bed0aac5fe8ff90dbbe345351edd8f01eddf Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Sun, 31 May 2026 14:02:09 +0000 Subject: [PATCH] Improve noexec robustness, security, and documentation - Refactor `src/noexec` to use `mktemp` for unique temporary filenames. - Add support for `-h`/`--help` and improve `-v`/`--version` handling in `src/noexec`. - Implement robust permission and file existence checks. - Enhance `docs/install.sh` with dependency and write permission checks. - Add a new test suite in `tests/test_noexec.sh`. - Update `README.md` to reflect new flags. Co-authored-by: ByteJoseph <131424720+ByteJoseph@users.noreply.github.com> --- README.md | 10 +++++- docs/install.sh | 44 +++++++++++++++++++++----- src/noexec | 73 +++++++++++++++++++++++++++++--------------- tests/test_noexec.sh | 50 ++++++++++++++++++++++++++++++ 4 files changed, 144 insertions(+), 33 deletions(-) create mode 100644 tests/test_noexec.sh diff --git a/README.md b/README.md index 229bd9e..8eb26e8 100644 --- a/README.md +++ b/README.md @@ -61,12 +61,20 @@ noexec --version ### Help -Display usage information (run without arguments): +Display usage information (run without arguments or with -h/--help): ```bash noexec ``` +```bash +noexec -h +``` + +```bash +noexec --help +``` + ### Credits Show author and project information: diff --git a/docs/install.sh b/docs/install.sh index 211d161..888b9c9 100644 --- a/docs/install.sh +++ b/docs/install.sh @@ -1,13 +1,43 @@ -curl "https://raw.githubusercontent.com/ByteJoseph/noexec/refs/heads/main/src/noexec" -o noexec +set -e + +# Check for required commands +for cmd in curl dirname command cp chmod rm; do + if ! command -v "$cmd" >/dev/null 2>&1; then + echo "Error: Required command '$cmd' not found. Please install it and try again." + exit 1 + fi +done + +echo "Downloading noexec..." +if ! curl -s "https://raw.githubusercontent.com/ByteJoseph/noexec/refs/heads/main/src/noexec" -o noexec; then + echo "Error: Failed to download noexec." + exit 1 +fi + file="noexec" -dir_name=$(dirname "$(command -v bash)") +bash_path=$(command -v bash) +if [ -z "$bash_path" ]; then + echo "Error: Could not find bash in PATH." + rm -f "$file" + exit 1 +fi + +dir_name=$(dirname "$bash_path") + +if [ ! -w "$dir_name" ]; then + echo "Error: No write permission to $dir_name. Please run with appropriate permissions." + rm -f "$file" + exit 1 +fi + if [ -f "$file" ]; then - cp "$file" "$dir_name/$file" chmod +x "$dir_name/$file" - echo "noexec Installed Successfully" - rm "noexec" + echo "noexec Installed Successfully to $dir_name/$file" + rm "$file" echo "" - echo "Start using now" - noexec + echo "Start using now by typing: noexec" +else + echo "Error: Downloaded file not found." + exit 1 fi diff --git a/src/noexec b/src/noexec index 6dbac64..8f24cb7 100644 --- a/src/noexec +++ b/src/noexec @@ -1,9 +1,11 @@ #!/bin/bash -version=1.0 +version=1.1 exe="$1" -if [ -z "$exe" ]; then - cat < │ │ │ @@ -13,12 +15,16 @@ if [ -z "$exe" ]; then │ Options: │ │ -v, --version Display the version and │ │ exit. │ +│ -h, --help Display this help and │ +│ exit. │ +│ --credits Display author and │ +│ project information. │ ╰────────────────────────────────────────────╯ EOF - exit 0 -fi -if [ "--credits" = "$exe" ]; then - cat <&2 + exit 1 +fi strip_target=$(dirname "$target") +if [ ! -w "$strip_target" ]; then + echo "Error: No write permission to $strip_target" >&2 + exit 1 +fi if [ -f "$exe" ]; then -year=$(date +%Y) -base="$(basename "$exe")" -temp_exec="$strip_target/${base}${year}" - -cp "$exe" "$temp_exec" -chmod +x "$temp_exec" -trap 'rm -f "$temp_exec"' EXIT -"$temp_exec" "${@:2}" -exit_code=$? -rm -f "$temp_exec" -exit $exit_code + base="$(basename "$exe")" + temp_exec=$(mktemp -p "$strip_target" "${base}.XXXXXXXX") || { + echo "Error: Failed to create temporary file in $strip_target" >&2 + exit 1 + } + trap 'rm -f "$temp_exec"' EXIT + + cp "$exe" "$temp_exec" || { + echo "Error: Failed to copy $exe to $temp_exec" >&2 + exit 1 + } + + chmod +x "$temp_exec" + "$temp_exec" "${@:2}" + exit_code=$? + exit $exit_code +elif [ -d "$exe" ]; then + echo "Error: '$exe' is a directory, not a file." >&2 + exit 1 else - echo "File $exe doesn't exist" + echo "Error: File '$exe' doesn't exist." >&2 exit 1 fi diff --git a/tests/test_noexec.sh b/tests/test_noexec.sh new file mode 100644 index 0000000..f109eae --- /dev/null +++ b/tests/test_noexec.sh @@ -0,0 +1,50 @@ +#!/bin/bash + +# Setup a fake bin directory and add it to PATH +FAKE_BIN="$(pwd)/fake_bin_test" +mkdir -p "$FAKE_BIN" +cp "$(command -v bash)" "$FAKE_BIN/bash" +export PATH="$FAKE_BIN:$PATH" + +NOEXEC="$(pwd)/src/noexec" + +# Helper for testing +assert_contains() { + local output="$1" + local expected="$2" + local name="$3" + if echo "$output" | grep -q "$expected"; then + echo "PASS: $name" + else + echo "FAIL: $name" + echo " Expected to contain: $expected" + echo " Actual output: $output" + exit 1 + fi +} + +# Test Case 1: Verify successful execution of a simple script passing arguments +echo 'echo "Test Output: $1 $2"' > test_script.sh +chmod +x test_script.sh +OUTPUT=$(bash "$NOEXEC" ./test_script.sh "Arg1" "Arg2") +assert_contains "$OUTPUT" "Test Output: Arg1 Arg2" "Successful execution with arguments" + +# Test Case 2: Verify correct output for the --help flag +OUTPUT=$(bash "$NOEXEC" --help) +assert_contains "$OUTPUT" "Usage : noexec" "Help flag output" + +# Test Case 3: Verify error message when the input file does not exist +OUTPUT=$(bash "$NOEXEC" non_existent_file 2>&1) +assert_contains "$OUTPUT" "Error: File 'non_existent_file' doesn't exist." "Missing file error" + +# Test Case 4: Verify error message when the input is a directory instead of a file +mkdir -p test_dir +OUTPUT=$(bash "$NOEXEC" test_dir 2>&1) +assert_contains "$OUTPUT" "Error: 'test_dir' is a directory, not a file." "Directory input error" + +# Cleanup +rm test_script.sh +rm -rf test_dir +rm -rf "$FAKE_BIN" + +echo "All tests passed!"