@@ -316,6 +316,21 @@ export class Util {
316316 }
317317 }
318318
319+ /**
320+ * Fairly aggressive sanitize removing anything but ASCII, numbers and a few needed chars that have no action:
321+ * - semicolons (:), dots (.), underscores (_) for paths/URLs
322+ * - dashes (-) & forward slashes (/) for packages and paths/URLs
323+ * - at (@), non-leading tilde (~) for package scope & version
324+ * @remarks
325+ * Most shells should be UTF-enabled, but current usage is very limited thus no need for `\p{L}`
326+ */
327+ public static sanitizeShellArg ( arg : string ) : string {
328+ return arg
329+ . replace ( / [ ^ a - z 0 - 9 @ : _ ~ \^ \/ \. \- ] / gi, '' ) // remove unsafe chars
330+ . replace ( / \^ (? ! \d ) / g, '' ) // keep only ^<digit>
331+ . replace ( / ^ ~ / , '' ) ; // remove leading ~
332+ }
333+
319334 /**
320335 * Execute synchronous command with options
321336 * @param command Command to be executed
@@ -348,29 +363,17 @@ export class Util {
348363 }
349364
350365 /**
351- * Execute synchronous command with options using spawnSync
352- * @param command Command to be executed
353- * @param args Command arguments
354- * @param options Command options
355- * @throws {Error } On non-zero exit code. Error has 'status', 'signal', 'output', 'stdout', 'stderr'
356- */
357- public static spawnSync ( command : string , args : string [ ] , options ?: SpawnSyncOptions ) {
358- try {
359- return spawnSync ( command , args , options ) ;
360- } catch ( error ) {
361- // Handle potential process interruption
362- // Check if the error output ends with "^C"
363- if ( error . stderr && error . stderr . toString ( ) . endsWith ( ) === "^C" ) {
364- return process . exit ( ) ;
365- }
366-
367- // Handle specific exit codes for different signals
368- if ( error . status === 3221225786 || error . status > 128 ) {
369- return process . exit ( ) ;
370- }
371-
372- throw error ;
373- }
366+ * Execute synchronous command with options using spawnSync
367+ * @param command Command to be executed
368+ * NOTE: `spawn` without `shell` (unsafe) is **not** equivalent to `exec` & requires `npm.cmd` to run the correct process on win
369+ * do not call with/add commands that are not known binaries without validating first
370+ * @param args Command arguments
371+ * @param options Command options
372+ * @returns {SpawnSyncReturns } object with status and stdout
373+ * @remarks Consuming code MUST handle the result and check for failure status!
374+ */
375+ public static spawnSync ( command : string , args : string [ ] , options ?: Omit < SpawnSyncOptions , 'shell' > ) {
376+ return spawnSync ( command , args , options ) ;
374377 }
375378
376379 /**
@@ -383,7 +386,7 @@ export class Util {
383386 const options : any = { cwd : path . join ( parentRoot , projectName ) , stdio : [ process . stdin , "ignore" , "ignore" ] } ;
384387 Util . execSync ( "git init" , options ) ;
385388 Util . execSync ( "git add ." , options ) ;
386- Util . execSync ( "git commit -m " + "\"Initial commit for project: " + projectName + " \"", options ) ;
389+ Util . execSync ( "git commit -m " + "\"Initial commit for project\"" , options ) ;
387390 Util . log ( Util . greenCheck ( ) + " Git Initialized and Project '" + projectName + "' Committed" ) ;
388391 } catch ( error ) {
389392 Util . error ( "Git initialization failed. Install Git in order to automatically commit the project." , "yellow" ) ;
0 commit comments