mirror of
https://fastgit.cc/github.com/Yeachan-Heo/oh-my-claudecode
synced 2026-04-20 12:51:30 +08:00
test(plugin-patterns): scope win32 shell-flag regex per call site
Codex review on #2722 correctly flagged that [\s\S]*? could cross call boundaries — dropping the shell flag from runTypeCheck could still pass if runTests or runLint kept theirs, because the lazy match would just continue past the end of the target call until it found the flag in a sibling options object. Replaced [\s\S]*? with [^}]*? and anchored the match to this call's own options-object boundaries (\{ … \}\s*\);), so each assertion fails independently when its target call loses the flag. Keep the option objects flat — nested braces would terminate [^}]*? prematurely. Confidence: high Scope-risk: narrow Directive: If future option objects nest braces (e.g. { env: { … } }), switch these to balanced-scan or per-call substring extraction — [^}]*? stops at the first inner }. Not-tested: Mutation-test that synthetically removes each shell flag and asserts each test fails independently.
This commit is contained in:
@@ -269,27 +269,32 @@ describe('win32 spawn hardening (#2721)', () => {
|
||||
// below spawn npm / npx, which resolve to npm.cmd / npx.cmd on Windows, so
|
||||
// each one needs shell:true gated on win32. CI is Ubuntu-only, so static
|
||||
// source assertions are the only regression guard.
|
||||
//
|
||||
// Each regex is scoped to a single options object via [^}]*? — if the shell
|
||||
// flag is dropped from this specific call site, the match cannot silently
|
||||
// succeed by finding the same flag in a sibling call below. Keep the
|
||||
// option objects flat (no nested braces) so this scoping holds.
|
||||
const testDirPath = dirname(fileURLToPath(import.meta.url));
|
||||
const sourcePath = join(testDirPath, '..', '..', 'hooks', 'plugin-patterns', 'index.ts');
|
||||
|
||||
it('runTypeCheck spawnSync("npx", …) must pass shell:true on win32', () => {
|
||||
const src = readFileSync(sourcePath, 'utf-8');
|
||||
expect(src).toMatch(
|
||||
/spawnSync\('npx', \['tsc', '--noEmit'\][\s\S]*?shell:\s*process\.platform === 'win32'/
|
||||
/spawnSync\('npx', \['tsc', '--noEmit'\], \{[^}]*?shell:\s*process\.platform === 'win32'[^}]*?\}\s*\);/
|
||||
);
|
||||
});
|
||||
|
||||
it('runTests execFileSync("npm test", …) must pass shell:true on win32', () => {
|
||||
const src = readFileSync(sourcePath, 'utf-8');
|
||||
expect(src).toMatch(
|
||||
/execFileSync\('npm', \['test'\][\s\S]*?shell:\s*process\.platform === 'win32'/
|
||||
/execFileSync\('npm', \['test'\], \{[^}]*?shell:\s*process\.platform === 'win32'[^}]*?\}\s*\);/
|
||||
);
|
||||
});
|
||||
|
||||
it('runLint execFileSync("npm run lint", …) must pass shell:true on win32', () => {
|
||||
const src = readFileSync(sourcePath, 'utf-8');
|
||||
expect(src).toMatch(
|
||||
/execFileSync\('npm', \['run', 'lint'\][\s\S]*?shell:\s*process\.platform === 'win32'/
|
||||
/execFileSync\('npm', \['run', 'lint'\], \{[^}]*?shell:\s*process\.platform === 'win32'[^}]*?\}\s*\);/
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user