diff --git a/inventory/inventory-graph.json b/inventory/inventory-graph.json index c64238b8e..f50354451 100644 --- a/inventory/inventory-graph.json +++ b/inventory/inventory-graph.json @@ -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" } diff --git a/src/hooks/__tests__/pre-tool-use-template-source-ext.test.ts b/src/hooks/__tests__/pre-tool-use-template-source-ext.test.ts index 39768d4ac..bbfdb6ffb 100644 --- a/src/hooks/__tests__/pre-tool-use-template-source-ext.test.ts +++ b/src/hooks/__tests__/pre-tool-use-template-source-ext.test.ts @@ -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], diff --git a/templates/hooks/pre-tool-use.mjs b/templates/hooks/pre-tool-use.mjs index e6d089e71..35bcef9f3 100644 --- a/templates/hooks/pre-tool-use.mjs +++ b/templates/hooks/pre-tool-use.mjs @@ -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]) }); }