Problem
extract_functions decides where a function ends by counting { and } on
each line, with no regard for quoting or comments. One unbalanced brace inside
a string or a comment therefore never balances out, and the function it is in
absorbs the rest of the file.
src/coverage/lines.sh is the worst case in this repo: 11 declarations, 1
extracted record. The running balance never returns to zero after three
lines that are not code at all:
21 bal=1 function bashunit::coverage::is_executable_line() {
60 bal=2 # Function declarations: `[function ]name()` with an optional trailing `{`.
72 bal=3 *'{')
73 bal=4 fn_rest="${fn_rest%'{'}"
122 bal=3 }
124 bal=4 function bashunit::coverage::get_executable_lines() { <- never recorded
Across src/: 13 files lose functions, 80 of 760 declarations missing.
Every one of them collapses to a single record spanning most of the file.
Impact
- LCOV
FN/FNDA name the wrong span, and FNF/FNH are undercounted, so
any consumer that reads function coverage (Coveralls, Codecov, SonarQube)
gets wrong data - The HTML and text function views show one huge function instead of the file
- A function whose span is wrong takes another function's hits as its own
Fix
Count braces only outside single quotes, double quotes and comments. A #
starts a comment only where bash starts one (start of line or after
whitespace), so ${x#foo} and a#b keep their braces.
Verifying it
Bash itself is the oracle: shopt -s extdebug + declare -F <name> reports
the file and start line of every function it sourced from src/, which pins
the extracted starts against the real ones (in a subshell — extdebug in the
parent clobbers caller state, #808).
Problem
extract_functionsdecides where a function ends by counting{and}oneach line, with no regard for quoting or comments. One unbalanced brace inside
a string or a comment therefore never balances out, and the function it is in
absorbs the rest of the file.
src/coverage/lines.shis the worst case in this repo: 11 declarations, 1extracted record. The running balance never returns to zero after three
lines that are not code at all:
Across
src/: 13 files lose functions, 80 of 760 declarations missing.Every one of them collapses to a single record spanning most of the file.
Impact
FN/FNDAname the wrong span, andFNF/FNHare undercounted, soany consumer that reads function coverage (Coveralls, Codecov, SonarQube)
gets wrong data
Fix
Count braces only outside single quotes, double quotes and comments. A
#starts a comment only where bash starts one (start of line or after
whitespace), so
${x#foo}anda#bkeep their braces.Verifying it
Bash itself is the oracle:
shopt -s extdebug+declare -F <name>reportsthe file and start line of every function it sourced from
src/, which pinsthe extracted starts against the real ones (in a subshell — extdebug in the
parent clobbers caller state, #808).