diff --git a/lib/checkrun/autolint.sh b/lib/checkrun/autolint.sh index b3584c2..05aa7b6 100644 --- a/lib/checkrun/autolint.sh +++ b/lib/checkrun/autolint.sh @@ -106,7 +106,15 @@ _autolint_read_files0() { # field for both EOF and descriptor errors. Reject a closed descriptor and # directory source before reading so an invalid stream cannot become a # silent no-op. Pipes, regular files, sockets, and terminals remain valid. - if { [ ! -r /dev/stdin ] && [ ! -r /dev/fd/0 ]; } || + # Test descriptor openness by duplicating fd 0 into a subshell rather + # than by probing /dev/stdin readability: on the ubuntu-26.04 runner + # a closed stdin arrives as /dev/null (the runner's bash reopens it + # at process startup, verified with a fresh `bash -c` probe), so the + # /dev probe passes and the read loop treats it as EOF. Duplicating + # a closed descriptor fails; duplicating an open one succeeds + # regardless of what it points at. (Duplicating fd 0 onto itself is + # a no-op even when closed, so the target must differ.) + if ! ( exec 3<&0 ) 2>/dev/null || [ -d /dev/stdin ] || [ -d /dev/fd/0 ]; then echo "autolint: --files0-from - requires a readable stream on standard input" >&2 return 2 diff --git a/test/suites/autolint-test b/test/suites/autolint-test index d434a1a..161f1a1 100755 --- a/test/suites/autolint-test +++ b/test/suites/autolint-test @@ -3056,7 +3056,13 @@ _assert_exit "files0 stdin: empty input is a no-op" 0 "$rc" _assert_eq "files0 stdin: empty input is quiet" "" "$output" set +e -output=$("$AUTOLINT" --files0-from - <&- 2>&1) +# Invoke in-process, not via bin/autolint: the ubuntu-26.04 runner's bash +# reopens /dev/null for a closed stdin at process startup (verified: a +# fresh `bash -c` probe with closed stdin arrives with fd 0 -> /dev/null), +# so a subprocess invocation can never observe the closed descriptor the +# guard is meant to reject. A command-substitution subshell forks without +# re-running bash startup, so the closed fd survives to _autolint_main. +output=$(. "$CHECKRUN_TEST_ROOT/lib/checkrun/autolint.sh"; _autolint_main --files0-from - <&- 2>&1) rc=$? set -e _assert_exit "files0 stdin: closed descriptor exits 2" 2 "$rc"