fix(ci): stop check-threading-doc aborting on bash 3.2 when a citation misses - #1325
Merged
Conversation
…n misses
resolve_reference_source iterated "${candidates[@]}" without checking the array
was non-empty. On bash 3.2 that is an unbound-variable error under `set -u`;
bash 4.4 changed it. So a prose citation naming a file that does not exist under
wirelog/ killed the checker with
check-threading-doc.sh: line 65: candidates[@]: unbound variable
instead of letting the caller report which citation failed to resolve. It cannot
cause a false pass -- the path is only reachable when the run was going to fail
anyway -- but it replaces the diagnostic with one that names an internal array.
threading_doc and threading_doc_selftest are registered in suite abi with no
platform gate, ci-pr.yml runs bare `meson test` on macos-latest in two jobs, and
those runners ship bash 3.2.57.
Guard both sites: the candidates loop, and the location_list loop four lines
below the new comment, which has the identical shape. The second is unreachable
today because the driving grep guarantees a non-empty post-colon part, but it is
one pattern edit from being live and the guard costs a line.
The self-test now invokes the checker as `"$BASH" "$checker"` rather than
through its shebang. That is the part that makes the new case able to fail: the
shebang resolves to the first bash on PATH, which need not be the interpreter
running the suite, so a portability defect only visible under the runner's bash
was masked. Verified -- with the shebang, deleting the guard leaves the new case
passing under bash 3.2.57; with "$BASH", it fails and names the abort. It also
makes the self-test agree with tests/meson.build:735, which already runs the
checker under find_program('bash').
Verified against GNU bash 3.2.57 built from source with all 57 official patches,
the version macOS ships. Note that unpatched 3.2.0 is not a faithful proxy: it
rejects this repository's inline `=~ ^([0-9]+)-([0-9]+)$` as a syntax error,
which 3.2.57 accepts.
Refs #1320
This was referenced Sep 2, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #1320. Based on
main— independent of the other open PRs.The bug
resolve_reference_sourceiterated"${candidates[@]}"without checking the array wasnon-empty. On bash 3.2 that is an unbound-variable error under
set -u; bash 4.4 changed it.So a prose citation naming a file that does not exist under
wirelog/killed the checkerwith
instead of letting the caller report which citation failed to resolve.
It cannot cause a false pass — the path is only reachable when the run was going to fail
anyway. It replaces the diagnostic with one naming an internal array.
threading_docandthreading_doc_selftestare registered in suiteabiwith no platformgate;
ci-pr.ymlruns baremeson testonmacos-latestin two jobs; those runners shipbash 3.2.57.
Verified against real bash 3.2.57, not by reasoning
I built GNU bash 3.2 from the tarball with all 57 official patches —
3.2.57(4)-release, theversion macOS ships — and ran everything against it.
Caveat worth recording for anyone repeating this: unpatched bash 3.2.0 additionally
rejects this repository's inline
[[ x =~ ^([0-9]+)-([0-9]+)$ ]]as a syntax error, which3.2.57 accepts. I initially concluded from a 3.2.0 build that the checker did not parse
on macOS at all — that was an artifact of the unpatched build, not a real CI failure. 3.2.0
is not a faithful proxy for the runner.
The change
check-threading-doc.sh— guard both empty-array iterations. Thecandidatesloop isthe live bug. The
location_listloop four lines below is the identical shape; it isunreachable today because the driving
grep -oEguarantees a non-empty post-colon part, butit is one pattern edit from being live and the guard costs a line. Verified on 3.2.57 that
the unguarded form aborts with
location_list[@]: unbound variableand the guarded formreports intelligibly.
test-threading-doc.sh— a case asserting an unresolvable citation produces thediagnostic and not an abort, plus every
"$checker"invocation changed to"$BASH" "$checker".That second part is what makes the new case able to fail at all. The shebang resolves to the
first
bashonPATH, which need not be the interpreter running the suite — so with theshebang, deleting the guard leaves the new case passing under 3.2.57. My first version of
this test was decoration and I only found that by mutating it. It also makes the self-test
agree with
tests/meson.build:735, which already runs the checker underfind_program('bash'); before, the self-test's inner checker used the runtime PATH bashwhile the sibling test used the configure-time bash, and the two could diverge.
Review
Reviewer approved, verifying against the same 3.2.57 binary. It confirmed the
"$BASH"change is strictly more faithful rather than merely different, that
return 1on an emptycandidate set is equivalent to the old fall-through and not merely similar, and that four
independent mutations each kill the new case.
Two things it found that are fixed here: a temp-directory leak I introduced (my new case
reassigned
fixtureand replaced the EXIT trap, orphaning the firstmktemp -devery run —now reuses the file's own
make_fixtureidiom, verified 0 leftovers under a controlledTMPDIRon both shells), and the latentlocation_listtwin above.It also found the same shape in
scripts/ci/check-abi-manifest.sh:124, whereabi/libwirelog-1.0.supprdoes not exist so the array is empty in the defaultconfiguration — masked only by libabigail being unavailable on macOS. Filed as #1324.
Local: 304 Ok / 0 Fail / 12 Skipped, serialized, dedicated build dir.