Skip to content

fix(bash,tests): real #315 multi-input bug + test infra path/ESM bugs - #555

Merged
Wolfvin merged 1 commit into
mainfrom
fix/bash-stack-test-and-crlf-multiinput
Jun 29, 2026
Merged

fix(bash,tests): real #315 multi-input bug + test infra path/ESM bugs#555
Wolfvin merged 1 commit into
mainfrom
fix/bash-stack-test-and-crlf-multiinput

Conversation

@Wolfvin

@Wolfvin Wolfvin commented Jun 29, 2026

Copy link
Copy Markdown
Owner

scripts/capture_bash.sh, scripts/validate_bash.sh — REAL execution-verified bug

invoke_entry()'s argument-passing pipeline writes args via jq -r, then reads them back via mapfile -t ARGS < "$args_file". jq.exe (Windows build) emits CRLF line endings on -r text output (same root cause as the confirmed jq-stack bug, #519/#529), and mapfile -t only strips the trailing \n, leaving every argument contaminated with a trailing \r.

This silently defeats exact string comparisons in user code — discovered via tests/bash-stack.test.js's #315 multi-input regression test, which mutates a function to special-case input #2 and expects validate to catch it. It didn't: the live arg never matched the literal string the mutation checked for, so validate silently PASSed a real behavioral regression.

Fixed by stripping \r from the file via tr -d '\r' (through process substitution) before mapfile reads it — a post-hoc ${ARGS[i]%$'\r'} strip after mapfile reproducibly does NOT take effect when nested inside this file's output=$( { ... } ) command-substitution structure (confirmed via isolated minimal repro; root cause of that specific bash behavior not fully understood, worked around instead).

tests/bash-stack.test.js — two test-infrastructure bugs (Windows-only)

  1. REPO_ROOT/SCRIPTS get embedded unquoted into bash -c command strings. On native Windows these are backslash-separated paths, and bash's own command-string parser treats every unquoted \X as an escaped literal X — silently dropping every backslash. Fixed by normalizing both to forward slashes once at the top.
  2. await import(join(SCRIPTS, 'validate.js')) passes a raw absolute path string to dynamic import(). Node's ESM loader on Windows requires a file:// URL. Fixed with pathToFileURL().

Verification

Cross-checked against GitHub Actions CI (Linux, green on main) to confirm the bulk of unrelated Windows-only npm test failures seen this session are test-runner artifacts (SIGINT/SIGTERM semantics) rather than product regressions — this one is a genuine product bug.

## scripts/capture_bash.sh, scripts/validate_bash.sh — REAL execution-verified bug

invoke_entry()'s argument-passing pipeline writes args via `jq -r`, then
reads them back via `mapfile -t ARGS < "$args_file"`. jq.exe (Windows
build) emits CRLF line endings on -r text output (same root cause as the
confirmed jq-stack bug, #519/#529), and `mapfile -t` only strips the
trailing `\n`, leaving every argument contaminated with a trailing `\r`
(e.g. "Hello, World!" becomes "Hello, World!\r").

This silently defeats exact string comparisons in user code -- discovered
via tests/bash-stack.test.js's #315 multi-input regression test, which
mutates a function to special-case input #2 ("Hello, World!") and expects
validate to catch it. It didn't: the live arg never matched the literal
string the mutation checked for, so the mutated branch was never taken,
and validate silently PASSed a real behavioral regression.

Initial fix attempt (strip \r from each array element via
`${ARGS[i]%$'\r'}` after mapfile) reproducibly does NOT work when nested
inside this file's `output=$( { ... } )` command-substitution structure
-- confirmed via isolated minimal repro that the exact same suffix-removal
pattern works at top level and inside a plain `( )` subshell, but
silently no-ops here. Root cause of THAT specific bash behavior is not
fully understood; worked around it by stripping \r from the file via
`tr -d '\r'` (through process substitution) BEFORE mapfile reads it,
which does work reliably.

## tests/bash-stack.test.js — two test-infrastructure bugs (Windows-only)

1. REPO_ROOT/SCRIPTS (computed via path.resolve()/join()) get embedded
   unquoted into bash -c command strings throughout this file. On native
   Windows these are backslash-separated paths, and bash's own command-
   string parser treats every unquoted '\X' as an escaped literal X --
   silently dropping every backslash ("C:\Users\user\foo" becomes
   "C:Usersuserfoo"), which then fails to resolve as a file path at all
   (status 127, "No such file or directory"). Fixed by normalizing both
   to forward slashes once at the top (valid path separator on Windows
   too) -- fixes every call site at once.

2. `await import(join(SCRIPTS, 'validate.js'))` passes a raw absolute
   path string to dynamic import(). Node's ESM loader on Windows requires
   a file:// URL for absolute-path imports, not a raw "c:/..." string
   (ERR_UNSUPPORTED_ESM_URL_SCHEME). Fixed with pathToFileURL().

## Verification

- Full manual repro outside the test suite: fresh capture -> 2/2 PASS ->
  mutate slugify() to special-case input #2 only -> validate -> exactly
  1/2 FAIL ("bash-slugify: INPUTS[1] hash mismatch", bash-greet still
  PASS) -> restore -> 2/2 PASS again.
- `node --test tests/bash-stack.test.js`: 13/13 pass, 0 fail (was 13
  failures before this fix, all stemming from the two test-infra bugs
  cascading into every test in the file).

These three bugs were found while investigating why a from-scratch
`npm test` run on Windows showed 91 failures despite this session's
direct, isolated manual verification of the Bash stack passing cleanly.
Cross-checked against GitHub Actions CI (Linux, green on main) to confirm
the bulk of those 91 failures are Windows-test-runner-specific artifacts
(SIGINT/SIGTERM semantics, this exact path-escaping class of bug) rather
than product regressions -- but this particular one (#315 multi-input
silently not caught) is a genuine product bug that happened to only
surface because the test assertion exercises a multi-input scenario that
this session's manual spot-checks did not happen to construct.
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@Wolfvin
Wolfvin merged commit b6f08bc into main Jun 29, 2026
6 checks passed
@Wolfvin
Wolfvin deleted the fix/bash-stack-test-and-crlf-multiinput branch June 29, 2026 15:39
@sonarqubecloud

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant