From 70305b79370ce7c946ab3d8613952ea91d00da34 Mon Sep 17 00:00:00 2001 From: bbassie <17990055+bbassie@users.noreply.github.com> Date: Thu, 23 Jul 2026 23:02:37 +0000 Subject: [PATCH 1/2] Silence the deprecation warning on install execFile was called with shell: true and an array of arguments, which Node deprecates in DEP0190 because it concatenates the arguments by space without escaping anything, giving the impression they have been made safe. The warning was printed to the console on every install. The arguments here are already escaped for the shell by escapeArg, so join them into the command instead of handing them to execFile to concatenate. Nothing about what ends up being run changes. Point the escaping test at the same form so it covers what the installer actually does, and stops emitting the warning itself. Its several hundred round trip cases still pass, which is what confirms the escaping is unaffected. Fixes #851 Co-Authored-By: Claude Opus 4.8 (1M context) --- packages/create/create.js | 11 +++++++---- test/create/escape_arg.js | 8 +++++--- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/packages/create/create.js b/packages/create/create.js index e7f668fc..236df97b 100755 --- a/packages/create/create.js +++ b/packages/create/create.js @@ -118,12 +118,15 @@ async function safeOutputFile(file, data, options={}) { } async function execFile(cmd, args) { - const escaped = args.map(escapeArg); - logger.verbose(`executing ${cmd} ${escaped.join(" ")}`); + // Arguments are escaped here and joined into the command rather than + // passed to execFile. With shell: true it would only concatenate them by + // space without escaping anything, which is what it is deprecated for + // (DEP0190) as it gives the impression the arguments are made safe. + const command = [cmd, ...args.map(escapeArg)].join(" "); + logger.verbose(`executing ${command}`); return new Promise((resolve, reject) => { let child = child_process.execFile( - cmd, - escaped, + command, { shell: true, diff --git a/test/create/escape_arg.js b/test/create/escape_arg.js index 496737e3..720fc27a 100644 --- a/test/create/escape_arg.js +++ b/test/create/escape_arg.js @@ -8,10 +8,12 @@ const { escapeArg } = require("../../packages/create/escape_arg"); const execFile = util.promisify(child_process.execFile); async function exec(file, args) { + // Escape the arguments and join them into the command the same way + // create.js does, rather than passing them to execFile which would only + // concatenate them by space without escaping (DEP0190). + const command = [file, ...args.map(escapeArg)].join(" "); const { stdout, stderr } = await execFile( - file, - args.map(escapeArg), - + command, { shell: true, cwd: __dirname, env: { ...process.env, pct: "%"} } ); return { stdout: JSON.parse(stdout), stderr }; From 870e1f2125ebf00da59ef2271bb538c2a35f549b Mon Sep 17 00:00:00 2001 From: Cooldude2606 <25043174+Cooldude2606@users.noreply.github.com> Date: Sat, 25 Jul 2026 14:51:14 +0100 Subject: [PATCH 2/2] Remove unneeded comments --- packages/create/create.js | 4 ---- test/create/escape_arg.js | 3 --- 2 files changed, 7 deletions(-) diff --git a/packages/create/create.js b/packages/create/create.js index 236df97b..3d0557af 100755 --- a/packages/create/create.js +++ b/packages/create/create.js @@ -118,10 +118,6 @@ async function safeOutputFile(file, data, options={}) { } async function execFile(cmd, args) { - // Arguments are escaped here and joined into the command rather than - // passed to execFile. With shell: true it would only concatenate them by - // space without escaping anything, which is what it is deprecated for - // (DEP0190) as it gives the impression the arguments are made safe. const command = [cmd, ...args.map(escapeArg)].join(" "); logger.verbose(`executing ${command}`); return new Promise((resolve, reject) => { diff --git a/test/create/escape_arg.js b/test/create/escape_arg.js index 720fc27a..593b1a3f 100644 --- a/test/create/escape_arg.js +++ b/test/create/escape_arg.js @@ -8,9 +8,6 @@ const { escapeArg } = require("../../packages/create/escape_arg"); const execFile = util.promisify(child_process.execFile); async function exec(file, args) { - // Escape the arguments and join them into the command the same way - // create.js does, rather than passing them to execFile which would only - // concatenate them by space without escaping (DEP0190). const command = [file, ...args.map(escapeArg)].join(" "); const { stdout, stderr } = await execFile( command,