Skip to content

Commit 945fcb7

Browse files
Copilotntotten
andcommitted
Fix code review issues: improve CLI args and security
Co-authored-by: ntotten <[email protected]>
1 parent 0e9c0ae commit 945fcb7

File tree

1 file changed

+15
-12
lines changed

1 file changed

+15
-12
lines changed

src/PrettierExecutableInstance.ts

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -158,14 +158,14 @@ export class PrettierExecutableInstance implements PrettierInstance {
158158
await this.import();
159159
}
160160

161-
const args = ["--config", "--resolve-config", fileName];
161+
const args = ["--resolve-config", fileName];
162162

163163
if (options?.config) {
164164
const config =
165165
typeof options.config === "string"
166166
? options.config
167167
: options.config.toString();
168-
args.push("--config", config);
168+
args.unshift("--config", config);
169169
}
170170

171171
if (options?.editorconfig === false) {
@@ -236,21 +236,25 @@ export class PrettierExecutableInstance implements PrettierInstance {
236236
// ${file} = file to format (if applicable)
237237
let command = this.customExecutable;
238238

239+
// Escape prettierPath to prevent command injection
240+
const escapedPrettierPath = this.escapeArg(this.prettierPath);
241+
239242
// If no ${prettier} placeholder exists, append it to the command
240243
if (!command.includes("${prettier}")) {
241-
command = `${command} ${this.prettierPath}`;
244+
command = `${command} ${escapedPrettierPath}`;
242245
} else {
243-
command = command.replace(/\$\{prettier\}/g, this.prettierPath);
246+
command = command.replace(/\$\{prettier\}/g, escapedPrettierPath);
244247
}
245248

246-
// Add arguments
249+
// Add arguments (these are already escaped in buildOptionsArgs)
247250
if (args) {
248251
command = `${command} ${args}`;
249252
}
250253

251254
// Replace ${file} placeholder if present
252255
if (filePath) {
253-
command = command.replace(/\$\{file\}/g, filePath);
256+
const escapedFilePath = this.escapeArg(filePath);
257+
command = command.replace(/\$\{file\}/g, escapedFilePath);
254258
}
255259

256260
return command;
@@ -357,11 +361,10 @@ export class PrettierExecutableInstance implements PrettierInstance {
357361
}
358362

359363
private escapeArg(arg: string): string {
360-
// Escape arguments for shell execution
361-
// Handle spaces and special characters
362-
if (arg.includes(" ") || arg.includes('"') || arg.includes("'")) {
363-
return `"${arg.replace(/"/g, '\\"')}"`;
364-
}
365-
return arg;
364+
// Escape arguments for shell execution to prevent command injection
365+
// Use single quotes for maximum safety, and escape any single quotes in the arg
366+
// This prevents shell interpretation of special characters
367+
// Replace single quotes with '\'' (end quote, escaped quote, start quote)
368+
return `'${arg.replace(/'/g, "'\\''")}'`;
366369
}
367370
}

0 commit comments

Comments
 (0)