fix(hooks): allow whitespace in stdin dup source fds

Parse 0<& 3 the same as 0<&3 so a heredoc on fd 3 still becomes
the shell program after duplication onto stdin.
This commit is contained in:
gaebal-gajae
2026-08-30 21:37:31 +00:00
parent 19212feca3
commit c882f25329
3 changed files with 7 additions and 6 deletions

View File

@@ -5,15 +5,15 @@
"provenance": {
"base": "05c800f40d1ad53b42a78609d2667ef4f726808b",
"planningHead": "0a91273e61dbbd47eb0af4c02844409251e08398",
"head": "31827de40f3b8569061f4e17eac817dd6655e511",
"sourceSha256": "59b8ab1e7e6478284099db6ecb07aa4c7b5e17be3772985a24fb9e3f83bf9903",
"head": "19212feca3586d715e19245dff4929b84377e2ec",
"sourceSha256": "de505fa800b1b4d55b257a03c81f30ed5621a7a3d54d07b6e6ef249273bd6c6e",
"generatedAt": null,
"generator": "scripts/generate-inventory-graph.mjs"
},
"base": "05c800f40d1ad53b42a78609d2667ef4f726808b",
"planningHead": "0a91273e61dbbd47eb0af4c02844409251e08398",
"head": "31827de40f3b8569061f4e17eac817dd6655e511",
"sourceSha256": "59b8ab1e7e6478284099db6ecb07aa4c7b5e17be3772985a24fb9e3f83bf9903",
"head": "19212feca3586d715e19245dff4929b84377e2ec",
"sourceSha256": "de505fa800b1b4d55b257a03c81f30ed5621a7a3d54d07b6e6ef249273bd6c6e",
"counts": {
"public": {
"skills": 35,
@@ -76776,5 +76776,5 @@
}
},
"inventorySha256": "f5ea9ebf29ba491f17b39431660e07f71eb3d78399d481c1c2b00fc34cf2ab50",
"manifestSha256": "e82e5705b56e4e97188176f7ed13cd7a2afd4ea066668fbe65b7ab7c04fdc971"
"manifestSha256": "e4a37ce662188e394ce3c832901617b56f0038a368224de2da1dd117506130f4"
}

View File

@@ -403,6 +403,7 @@ describe('pre-tool-use template source extension detection', () => {
['printf long unicode format escape assembles redirect', "printf 'echo x \\U0000003e %s\\n' src/app.ts | bash", true],
['heredoc producer piped into a stdin shell', "cat <<'EOF' | bash\necho x > src/app.ts\nEOF", true],
['nonzero heredoc duplicated onto stdin is a program', "bash 3<<'EOF' 0<&3\necho x > src/app.ts\nEOF", true],
['spaced dup source fd still transfers stdin', "bash 3<<'EOF' 0<& 3\necho x > src/app.ts\nEOF", true],
['printf %b expands argument escapes into a stdin program', "printf '%b' 'true\\necho x > src/app.ts\\n' | bash", true],
['printf %b expands octal argument escapes into a stdin program', "printf '%b' 'true\\012echo x > src/app.ts\\012' | bash", true],
['printf %b expands hex argument escapes into a stdin program', "printf '%b' 'true\\x0aecho x > src/app.ts\\x0a' | bash", true],

View File

@@ -646,7 +646,7 @@ function dupRedirects(line) {
const prefix = line.slice(0, i);
const destMatch = prefix.match(/(\d+)$/);
const dest = destMatch ? Number(destMatch[1]) : 0;
const srcMatch = line.slice(i + 2).match(/^(\d+)/);
const srcMatch = line.slice(i + 2).match(/^[ \t]*(\d+)/);
if (!srcMatch) continue;
dups.push({ pos: i, dest, src: Number(srcMatch[1]) });
}