@@ -249,15 +249,13 @@ const PIPE = (() => {
249249// `$node --abort-on-uncaught-exception $file child`
250250// the process aborts.
251251function childShouldThrowAndAbort ( ) {
252- let testCmd = '' ;
252+ const escapedArgs = escapePOSIXShell `" ${ process . argv [ 0 ] } " --abort-on-uncaught-exception " ${ process . argv [ 1 ] } " child` ;
253253 if ( ! isWindows ) {
254254 // Do not create core files, as it can take a lot of disk space on
255255 // continuous testing and developers' machines
256- testCmd + = 'ulimit -c 0 && ' ;
256+ escapedArgs [ 0 ] = 'ulimit -c 0 && ' + escapedArgs [ 0 ] ;
257257 }
258- testCmd += `"${ process . argv [ 0 ] } " --abort-on-uncaught-exception ` ;
259- testCmd += `"${ process . argv [ 1 ] } " child` ;
260- const child = exec ( testCmd ) ;
258+ const child = exec ( ...escapedArgs ) ;
261259 child . on ( 'exit' , function onExit ( exitCode , signal ) {
262260 const errMsg = 'Test should have aborted ' +
263261 `but instead exited with exit code ${ exitCode } ` +
@@ -944,13 +942,40 @@ function expectRequiredModule(mod, expectation, checkESModule = true) {
944942 assert . deepStrictEqual ( clone , { ...expectation } ) ;
945943}
946944
945+
946+ /**
947+ * Escape quoted values in a string template literal. On Windows, this function
948+ * does not escape anything (which is fine for paths, as `"` is not a valid char
949+ * in a path on Windows), so you should use it only to escape paths – or other
950+ * values on tests which are skipped on Windows.
951+ * @returns {[string, object | undefined] } An array that can be passed as
952+ * arguments to `exec` or `execSync`.
953+ */
954+ function escapePOSIXShell ( cmdParts , ...args ) {
955+ if ( common . isWindows ) {
956+ // On Windows, paths cannot contain `"`, so we can return the string unchanged.
957+ return [ String . raw ( { raw : cmdParts } , ...args ) ] ;
958+ }
959+ // On POSIX shells, we can pass values via the env, as there's a standard way for referencing a variable.
960+ const env = { ...process . env } ;
961+ let cmd = cmdParts [ 0 ] ;
962+ for ( let i = 0 ; i < args . length ; i ++ ) {
963+ const envVarName = `ESCAPED_${ i } ` ;
964+ env [ envVarName ] = args [ i ] ;
965+ cmd += '${' + envVarName + '}' + cmdParts [ i + 1 ] ;
966+ }
967+
968+ return [ cmd , { env } ] ;
969+ }
970+
947971const common = {
948972 allowGlobals,
949973 buildType,
950974 canCreateSymLink,
951975 childShouldThrowAndAbort,
952976 createZeroFilledFile,
953977 defaultAutoSelectFamilyAttemptTimeout,
978+ escapePOSIXShell,
954979 expectsError,
955980 expectRequiredModule,
956981 expectWarning,
0 commit comments