Skip to content

Commit 9235356

Browse files
committed
fix: use local -a for safe Bash 3.0 array init, fix variable scoping
1 parent 46f94b6 commit 9235356

9 files changed

Lines changed: 43 additions & 62 deletions

File tree

src/assert.sh

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -668,8 +668,7 @@ function assert_line_count() {
668668
bashunit::assert::should_skip && return 0
669669

670670
local expected="$1"
671-
# Bash 3.0 compatible array initialization
672-
local input_arr; [[ $# -gt 1 ]] && input_arr=("${@:2}")
671+
local -a input_arr=(); [[ $# -gt 1 ]] && input_arr=("${@:2}")
673672
local input_str
674673
input_str=$(printf '%s\n' ${input_arr+"${input_arr[@]}"})
675674

src/assert_arrays.sh

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,7 @@ function assert_array_contains() {
1010
label="$(bashunit::helper::normalize_test_function_name "$test_fn")"
1111
shift
1212

13-
# Bash 3.0 compatible array initialization
14-
local actual; [[ $# -gt 0 ]] && actual=("$@")
13+
local -a actual=(); [[ $# -gt 0 ]] && actual=("$@")
1514

1615
if ! [[ "${actual[*]:-}" == *"$expected"* ]]; then
1716
bashunit::assert::mark_failed
@@ -31,8 +30,7 @@ function assert_array_not_contains() {
3130
local label
3231
label="$(bashunit::helper::normalize_test_function_name "$test_fn")"
3332
shift
34-
# Bash 3.0 compatible array initialization
35-
local actual; [[ $# -gt 0 ]] && actual=("$@")
33+
local -a actual=(); [[ $# -gt 0 ]] && actual=("$@")
3634

3735
if [[ "${actual[*]:-}" == *"$expected"* ]]; then
3836
bashunit::assert::mark_failed

src/benchmark.sh

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,7 @@ function bashunit::benchmark::run_function() {
6262
local revs=$2
6363
local its=$3
6464
local max_ms=$4
65-
# Declare without =() for Bash 3.0 compatibility with set -u
66-
local durations
65+
local -a durations=()
6766
local durations_count=0
6867

6968
for ((i=1; i<=its; i++)); do

src/coverage.sh

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,7 @@ _BASHUNIT_COVERAGE_TEST_HITS_FILE="${_BASHUNIT_COVERAGE_TEST_HITS_FILE:-}"
1919
function bashunit::coverage::auto_discover_paths() {
2020
local project_root
2121
project_root="$(pwd)"
22-
# Bash 3.0 compatible array initialization
23-
local discovered_paths
22+
local -a discovered_paths=()
2423
local discovered_paths_count=0
2524

2625
for test_file in "$@"; do
@@ -765,8 +764,7 @@ function bashunit::coverage::report_html() {
765764
# Collect file data for index
766765
local total_executable=0
767766
local total_hit=0
768-
# Declare without =() for Bash 3.0 compatibility with set -u
769-
local file_data
767+
local -a file_data=()
770768
local file_data_count=0
771769

772770
while IFS= read -r file; do
@@ -818,7 +816,7 @@ function bashunit::coverage::generate_index_html() {
818816
local tests_failed="$7"
819817
shift 7
820818
# Handle array passed as arguments - Bash 3.0 compatible
821-
local file_data
819+
local -a file_data=()
822820
local file_count=0
823821
if [[ $# -gt 0 ]]; then
824822
file_data=("$@")
@@ -1175,8 +1173,7 @@ function bashunit::coverage::generate_file_html() {
11751173
local uncovered=$((executable - hit))
11761174

11771175
# Pre-load all line hits into indexed array (performance optimization)
1178-
# Bash 3.0 compatible: declare without =()
1179-
local hits_by_line
1176+
local -a hits_by_line=()
11801177
local _ln _cnt
11811178
while IFS=: read -r _ln _cnt; do
11821179
hits_by_line[_ln]=$_cnt
@@ -1185,8 +1182,7 @@ function bashunit::coverage::generate_file_html() {
11851182
# Pre-load test hits data into indexed array (for tooltips)
11861183
# Index: line number, Value: newline-separated list of "test_file:test_function"
11871184
# Using indexed array for Bash 3.0 compatibility (no associative arrays)
1188-
# Bash 3.0 compatible: declare without =()
1189-
local tests_by_line
1185+
local -a tests_by_line=()
11901186
local _line_and_test
11911187
while IFS= read -r _line_and_test; do
11921188
[[ -z "$_line_and_test" ]] && continue

src/helpers.sh

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,7 @@ function bashunit::helper::escape_single_quotes() {
9393
function bashunit::helper::interpolate_function_name() {
9494
local function_name="$1"
9595
shift
96-
# Bash 3.0 compatible array initialization
97-
local args
96+
local -a args=()
9897
local args_count=$#
9998
[[ $# -gt 0 ]] && args=("$@")
10099
local result="$function_name"
@@ -339,15 +338,15 @@ function bashunit::helper::find_total_tests() {
339338
340339
local count=0
341340
if [[ -n "$filtered_functions" ]]; then
342-
# Bash 3.0 compatible: separate declaration and assignment for arrays
343-
local functions_to_run
341+
local -a functions_to_run=()
344342
# shellcheck disable=SC2206
345343
functions_to_run=($filtered_functions)
344+
# shellcheck disable=SC2034
345+
local -a provider_data=()
346+
local provider_data_count=0
346347
for fn_name in "${functions_to_run[@]}"; do
347-
# Declare without =() for Bash 3.0 compatibility with set -u
348-
# shellcheck disable=SC2034
349-
local provider_data
350-
local provider_data_count=0
348+
provider_data=()
349+
provider_data_count=0
351350
while IFS=" " read -r line; do
352351
[[ -z "$line" ]] && continue
353352
# shellcheck disable=SC2034

src/learn.sh

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1157,8 +1157,7 @@ function test_backup_failure_when_source_missing() {
11571157
fi
11581158

11591159
# Verify the test has key components
1160-
# Declare without =() for Bash 3.0 compatibility with set -u
1161-
local missing_components
1160+
local -a missing_components=()
11621161
local missing_components_count=0
11631162

11641163
if ! grep -q "function set_up()" "$test_file"; then

src/main.sh

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,9 @@
55
#############################
66
function bashunit::main::cmd_test() {
77
local filter=""
8-
# Declare without =() for Bash 3.0 compatibility with set -u
9-
local raw_args
8+
local -a raw_args=()
109
local raw_args_count=0
11-
local args
10+
local -a args=()
1211
local args_count=0
1312
local assert_fn=""
1413
local _bashunit_coverage_opt_set=false
@@ -258,10 +257,9 @@ function bashunit::main::cmd_test() {
258257
#############################
259258
function bashunit::main::cmd_bench() {
260259
local filter=""
261-
# Declare without =() for Bash 3.0 compatibility with set -u
262-
local raw_args
260+
local -a raw_args=()
263261
local raw_args_count=0
264-
local args
262+
local -a args=()
265263
local args_count=0
266264

267265
export BASHUNIT_BENCH_MODE=true
@@ -621,8 +619,7 @@ function bashunit::main::handle_stop_on_failure_sync() {
621619

622620
function bashunit::main::exec_assert() {
623621
local original_assert_fn=$1
624-
# Bash 3.0 compatible array initialization
625-
local args
622+
local -a args=()
626623
local args_count=$(($# - 1))
627624
[[ $# -gt 1 ]] && args=("${@:2}")
628625

src/runner.sh

Lines changed: 20 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,9 @@ function bashunit::runner::restore_workdir() {
1515
function bashunit::runner::load_test_files() {
1616
local filter=$1
1717
shift
18-
# Bash 3.0 compatible array initialization
19-
local files
18+
local -a files=()
2019
[[ $# -gt 0 ]] && files=("$@")
21-
# Declare without =() for Bash 3.0 compatibility with set -u
22-
local scripts_ids
20+
local -a scripts_ids=()
2321
local scripts_ids_count=0
2422

2523
# Initialize coverage tracking if enabled
@@ -112,8 +110,7 @@ function bashunit::runner::load_test_files() {
112110
function bashunit::runner::load_bench_files() {
113111
local filter=$1
114112
shift
115-
# Bash 3.0 compatible array initialization
116-
local files
113+
local -a files=()
117114
[[ $# -gt 0 ]] && files=("$@")
118115

119116
for bench_file in ${files+"${files[@]}"}; do
@@ -207,8 +204,7 @@ function bashunit::runner::parse_data_provider_args() {
207204
local i
208205
local arg
209206
local encoded_arg
210-
# Bash 3.0 compatible array initialization
211-
local args
207+
local -a args=()
212208
local args_count=0
213209

214210
# Check for shell metacharacters that would break eval or cause globbing
@@ -313,8 +309,7 @@ function bashunit::runner::call_test_functions() {
313309
local filtered_functions
314310
filtered_functions=$(bashunit::helper::get_functions_to_run \
315311
"$prefix" "$filter" "$_BASHUNIT_CACHED_ALL_FUNCTIONS")
316-
# Bash 3.0 compatible array initialization
317-
local functions_to_run
312+
local -a functions_to_run=()
318313
local functions_to_run_count=0
319314
local _fn
320315
while IFS= read -r _fn; do
@@ -329,15 +324,18 @@ function bashunit::runner::call_test_functions() {
329324

330325
bashunit::helper::check_duplicate_functions "$script" || true
331326

327+
local -a provider_data=()
328+
local provider_data_count=0
329+
local -a parsed_data=()
330+
local parsed_data_count=0
331+
332332
for fn_name in "${functions_to_run[@]}"; do
333333
if bashunit::parallel::is_enabled && bashunit::parallel::must_stop_on_failure; then
334334
break
335335
fi
336336

337-
# Bash 3.0 compatible: unset before redeclaring to clear previous iteration's data
338-
unset provider_data
339-
local provider_data
340-
local provider_data_count=0
337+
provider_data=()
338+
provider_data_count=0
341339
while IFS=" " read -r line; do
342340
[[ -z "$line" ]] && continue
343341
provider_data[provider_data_count]="$line"
@@ -347,24 +345,22 @@ function bashunit::runner::call_test_functions() {
347345
# No data provider found
348346
if [[ "$provider_data_count" -eq 0 ]]; then
349347
bashunit::runner::run_test "$script" "$fn_name"
350-
unset fn_name
348+
unset -v fn_name
351349
continue
352350
fi
353351

354352
# Execute the test function for each line of data
355353
for data in "${provider_data[@]}"; do
356-
# Bash 3.0 compatible: unset before redeclaring to clear previous iteration's data
357-
unset parsed_data
358-
local parsed_data
359-
local parsed_data_count=0
354+
parsed_data=()
355+
parsed_data_count=0
360356
while IFS= read -r line; do
361357
[[ -z "$line" ]] && continue
362358
parsed_data[parsed_data_count]="$(bashunit::helper::decode_base64 "${line}")"
363359
parsed_data_count=$((parsed_data_count + 1))
364360
done <<< "$(bashunit::runner::parse_data_provider_args "$data")"
365361
bashunit::runner::run_test "$script" "$fn_name" ${parsed_data+"${parsed_data[@]}"}
366362
done
367-
unset fn_name
363+
unset -v fn_name
368364
done
369365
}
370366

@@ -377,8 +373,7 @@ function bashunit::runner::call_bench_functions() {
377373
local filtered_functions
378374
filtered_functions=$(bashunit::helper::get_functions_to_run \
379375
"$prefix" "$filter" "$_BASHUNIT_CACHED_ALL_FUNCTIONS")
380-
# Bash 3.0 compatible array initialization
381-
local functions_to_run
376+
local -a functions_to_run=()
382377
local functions_to_run_count=0
383378
local _fn
384379
while IFS= read -r _fn; do
@@ -398,7 +393,7 @@ function bashunit::runner::call_bench_functions() {
398393
for fn_name in "${functions_to_run[@]}"; do
399394
read -r revs its max_ms <<< "$(bashunit::benchmark::parse_annotations "$fn_name" "$script")"
400395
bashunit::benchmark::run_function "$fn_name" "$revs" "$its" "$max_ms"
401-
unset fn_name
396+
unset -v fn_name
402397
done
403398

404399
if ! bashunit::env::is_simple_output_enabled; then
@@ -726,8 +721,7 @@ function bashunit::runner::parse_result() {
726721
shift
727722
local execution_result=$1
728723
shift
729-
# Bash 3.0 compatible array initialization
730-
local args
724+
local -a args=()
731725
[[ $# -gt 0 ]] && args=("$@")
732726

733727
if bashunit::parallel::is_enabled; then
@@ -742,8 +736,7 @@ function bashunit::runner::parse_result_parallel() {
742736
shift
743737
local execution_result=$1
744738
shift
745-
# Bash 3.0 compatible array initialization
746-
local args
739+
local -a args=()
747740
[[ $# -gt 0 ]] && args=("$@")
748741

749742
local test_suite_dir="${TEMP_DIR_PARALLEL_TEST_SUITE}/$(basename "$test_file" .sh)"

src/state.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,7 @@ function bashunit::state::calculate_total_assertions() {
252252
local numbers
253253
numbers=$(echo "$input" | grep -oE '##ASSERTIONS_\w+=[0-9]+' | grep -oE '[0-9]+')
254254

255+
local number
255256
for number in $numbers; do
256257
total=$((total + number))
257258
done

0 commit comments

Comments
 (0)