test: run assembled setup harness scripts from a temp file, not bash -c argv (Windows MSYS2 8 KB truncation)

windows-free-tests (run 33907177851) failed in
test/setup-alias-name-uniqueness.test.ts with
  bash: -c: line 178: unexpected EOF while looking for matching `'
The harness slices functions out of `setup` and passed the joined script as
one `bash -c` argv element. The ownership gate grew that script from 6.7 KB
to 15.7 KB, and on Windows bash is an MSYS2 program: when its parent is a
non-MSYS process (bun), msys-2.0.dll's build_argv() runs any argument
containing `?*["'(){}` through globify()/glob(), which copies the pattern
into a fixed `Char patbuf[8192]` and silently stops after 8192 - MB_CUR_MAX
(8186 chars under C.UTF-8); GLOB_NOCHECK then returns the truncated text as
the argument. Character 8186 lands inside the single-quoted sed token on
line 178. Rebuilding the exact script with CI path shapes and cutting it at
8186-8190 characters reproduces the identical message locally; cmd.exe's
8191-UTF-16 cap and CreateProcess's 32767 do not fit the evidence.

Fix: test/helpers/bash-script.ts writes the script to a temp file and runs
`bash <path>` — a short glob-free argument that never enters globify. Every
setup harness that assembled a script for `bash -c` (11 files, 22 sites)
uses it; timeouts and env are preserved verbatim, spawn/timeout errors are
appended to stderr, temp cleanup is best-effort. `spawnSync('bash',
[<Windows absolute path>])` already passes on windows-latest in setup-help,
uninstall-windows-copies and the migration tests. The Windows-curated list
is byte-identical before and after.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Garry Tan
2026-09-04 23:05:59 +00:00
co-authored by Claude Fable 5.1
parent e64bab7a00
commit 1204828699
12 changed files with 92 additions and 42 deletions
+3 -3
View File
@@ -16,7 +16,7 @@
* corrupted the generated SKILL.md — the source files must stay byte-intact.
*/
import { describe, test, expect, beforeAll, afterAll } from 'bun:test';
import { spawnSync } from 'child_process';
import { runBashScript } from './helpers/bash-script';
import * as fs from 'fs';
import * as os from 'os';
import * as path from 'path';
@@ -74,7 +74,7 @@ beforeAll(() => {
installOnce,
installOnce,
].join('\n');
const result = spawnSync('bash', ['-c', script], { encoding: 'utf-8', timeout: 60_000 });
const result = runBashScript(script, { timeout: 60_000 });
if (result.status !== 0) {
throw new Error(`alias install failed: ${result.stderr}\n${result.stdout}`);
}
@@ -168,7 +168,7 @@ describe('alias installs are rewritten copies (#2511, #2201)', () => {
extractFn('link_claude_root_skill_alias'),
`link_claude_root_skill_alias "${ROOT}" "${legacyDir}"`,
].join('\n');
const result = spawnSync('bash', ['-c', script], { encoding: 'utf-8', timeout: 30_000 });
const result = runBashScript(script, { timeout: 30_000 });
expect(result.status).toBe(0);
const aliasSkill = path.join(aliasDir, 'SKILL.md');