run: give _testmarktest_relabel's locals its nameref's prefix, so a caller's variable of any name can be relabeled.
commit f074f81300cade746e2675b8fc348dd415f02f2e · parent e556796862
· browse this tree
Ximianth, 2026-10-25 12:05:27 UTC
A nameref resolves by name at each use, so the function's own locals shadowed a caller's variable of the same name: relabeling a variable named body relabeled the function's local instead, and left the caller's alone. testmarktest_rule's runner hit this; it uses another name, but the trap shouldn't be there for the next caller.
diff --git a/lib/testmark/run.bash b/lib/testmark/run.bash index 3d7718b..b059ff2 100644 --- a/lib/testmark/run.bash +++ b/lib/testmark/run.bash @@ -290,22 +290,22 @@ _testmarktest_relabel() { local -n _tmr_stream=$1 # Most output holds none of bash's own errors, and is left as it is, without a walk. [[ $_tmr_stream == */dev/fd/* ]] || return 0 - local -a fns=("$2" "${_testmarktest_provided[@]}") lines - local i j prefix body num + local -a _tmr_fns=("$2" "${_testmarktest_provided[@]}") _tmr_lines + local _tmr_i _tmr_j _tmr_prefix _tmr_body _tmr_num # Split once, keeping each line's newline: taking each line off the front of the string would copy the rest every time, quadratic in the output's size. - mapfile lines < <(printf '%s' "$_tmr_stream") - for i in "${!lines[@]}"; do - [[ ${lines[i]} == /dev/fd/* ]] || continue - for j in "${!fns[@]}"; do - prefix="/dev/fd/$((_testmarktest_fdbase + j)): line " - [[ ${lines[i]} == "$prefix"* ]] || continue - body=${lines[i]#"$prefix"} - num=${body%%:*} - if [[ -n $num && $num != *[!0-9]* && $body == "$num: "* ]]; then - lines[i]="${fns[j]}: ${body#"$num": }" + mapfile _tmr_lines < <(printf '%s' "$_tmr_stream") + for _tmr_i in "${!_tmr_lines[@]}"; do + [[ ${_tmr_lines[_tmr_i]} == /dev/fd/* ]] || continue + for _tmr_j in "${!_tmr_fns[@]}"; do + _tmr_prefix="/dev/fd/$((_testmarktest_fdbase + _tmr_j)): line " + [[ ${_tmr_lines[_tmr_i]} == "$_tmr_prefix"* ]] || continue + _tmr_body=${_tmr_lines[_tmr_i]#"$_tmr_prefix"} + _tmr_num=${_tmr_body%%:*} + if [[ -n $_tmr_num && $_tmr_num != *[!0-9]* && $_tmr_body == "$_tmr_num: "* ]]; then + _tmr_lines[_tmr_i]="${_tmr_fns[_tmr_j]}: ${_tmr_body#"$_tmr_num": }" fi break done done - printf -v _tmr_stream '%s' "${lines[@]}" + printf -v _tmr_stream '%s' "${_tmr_lines[@]}" }