testmark-bash

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[@]}"
 }