@@ -23,7 +23,18 @@ const which = {
2323}
2424
2525const path = require ( 'path' )
26- const tmpdir = path . resolve ( t . testdir ( ) )
26+ // we make our fake temp dir contain spaces for extra safety in paths with spaces
27+ const tmpdir = path . resolve ( t . testdir ( { 'with spaces' : { } } ) , 'with spaces' )
28+
29+ // used for unescaping windows path to script file
30+ const unescapeCmd = ( input ) => input
31+ . replace ( / ^ \^ " / , '' )
32+ . replace ( / \^ " $ / , '' )
33+ . replace ( / \^ ( .) / g, '$1' )
34+
35+ const unescapeSh = ( input ) => input
36+ . replace ( / ^ ' / , '' )
37+ . replace ( / ' $ / , '' )
2738
2839const makeSpawnArgs = requireInject ( '../lib/make-spawn-args.js' , {
2940 fs : {
@@ -68,7 +79,7 @@ if (isWindows) {
6879 cmd : 'script "quoted parameter"; second command' ,
6980 } )
7081 t . equal ( shell , 'cmd' , 'default shell applies' )
71- t . match ( args , [ '/d' , '/s' , '/c' , / \. c m d $ / ] , 'got expected args' )
82+ t . match ( args , [ '/d' , '/s' , '/c' , / \. c m d \^ " $ / ] , 'got expected args' )
7283 t . match ( opts , {
7384 env : {
7485 npm_package_json : / p a c k a g e \. j s o n $ / ,
@@ -81,11 +92,12 @@ if (isWindows) {
8192 windowsVerbatimArguments : true ,
8293 } , 'got expected options' )
8394
84- const contents = fs . readFileSync ( args [ args . length - 1 ] , { encoding : 'utf8' } )
95+ const filename = unescapeCmd ( args [ args . length - 1 ] )
96+ const contents = fs . readFileSync ( filename , { encoding : 'utf8' } )
8597 t . equal ( contents , `@echo off\nscript "quoted parameter"; second command` )
86- t . ok ( fs . existsSync ( args [ args . length - 1 ] ) , 'script file was written' )
98+ t . ok ( fs . existsSync ( filename ) , 'script file was written' )
8799 cleanup ( )
88- t . not ( fs . existsSync ( args [ args . length - 1 ] ) , 'cleanup removes script file' )
100+ t . not ( fs . existsSync ( filename ) , 'cleanup removes script file' )
89101
90102 t . end ( )
91103 } )
@@ -103,7 +115,7 @@ if (isWindows) {
103115 cmd : 'script "quoted parameter"; second command' ,
104116 } )
105117 t . equal ( shell , 'blrorp' , 'used ComSpec as default shell' )
106- t . match ( args , [ '-c' , / \. s h $ / ] , 'got expected args' )
118+ t . match ( args , [ '-c' , / \. s h ' $ / ] , 'got expected args' )
107119 t . match ( opts , {
108120 env : {
109121 npm_package_json : / p a c k a g e \. j s o n $ / ,
@@ -115,9 +127,10 @@ if (isWindows) {
115127 windowsVerbatimArguments : undefined ,
116128 } , 'got expected options' )
117129
118- t . ok ( fs . existsSync ( args [ args . length - 1 ] ) , 'script file was written' )
130+ const filename = unescapeSh ( args [ args . length - 1 ] )
131+ t . ok ( fs . existsSync ( filename ) , 'script file was written' )
119132 cleanup ( )
120- t . not ( fs . existsSync ( args [ args . length - 1 ] ) , 'cleanup removes script file' )
133+ t . not ( fs . existsSync ( filename ) , 'cleanup removes script file' )
121134
122135 t . end ( )
123136 } )
@@ -131,7 +144,7 @@ if (isWindows) {
131144 scriptShell : 'cmd.exe' ,
132145 } )
133146 t . equal ( shell , 'cmd.exe' , 'kept cmd.exe' )
134- t . match ( args , [ '/d' , '/s' , '/c' , / \. c m d $ / ] , 'got expected args' )
147+ t . match ( args , [ '/d' , '/s' , '/c' , / \. c m d \^ " $ / ] , 'got expected args' )
135148 t . match ( opts , {
136149 env : {
137150 npm_package_json : / p a c k a g e \. j s o n $ / ,
@@ -143,9 +156,10 @@ if (isWindows) {
143156 windowsVerbatimArguments : true ,
144157 } , 'got expected options' )
145158
146- t . ok ( fs . existsSync ( args [ args . length - 1 ] ) , 'script file was written' )
159+ const filename = unescapeCmd ( args [ args . length - 1 ] )
160+ t . ok ( fs . existsSync ( filename ) , 'script file was written' )
147161 cleanup ( )
148- t . not ( fs . existsSync ( args [ args . length - 1 ] ) , 'cleanup removes script file' )
162+ t . not ( fs . existsSync ( filename ) , 'cleanup removes script file' )
149163
150164 t . end ( )
151165 } )
@@ -161,7 +175,7 @@ if (isWindows) {
161175 args : [ '"quoted parameter";' , 'second command' ] ,
162176 } )
163177 t . equal ( shell , 'cmd' , 'default shell applies' )
164- t . match ( args , [ '/d' , '/s' , '/c' , / \. c m d $ / ] , 'got expected args' )
178+ t . match ( args , [ '/d' , '/s' , '/c' , / \. c m d \^ " $ / ] , 'got expected args' )
165179 t . match ( opts , {
166180 env : {
167181 npm_package_json : / p a c k a g e \. j s o n $ / ,
@@ -174,11 +188,12 @@ if (isWindows) {
174188 windowsVerbatimArguments : true ,
175189 } , 'got expected options' )
176190
177- const contents = fs . readFileSync ( args [ args . length - 1 ] , { encoding : 'utf8' } )
178- t . equal ( contents , `@echo off\nscript ^"\\^"quoted parameter\\^";^" ^"second command^"` )
179- t . ok ( fs . existsSync ( args [ args . length - 1 ] ) , 'script file was written' )
191+ const filename = unescapeCmd ( args [ args . length - 1 ] )
192+ const contents = fs . readFileSync ( filename , { encoding : 'utf8' } )
193+ t . equal ( contents , `@echo off\nscript ^"\\^"quoted^ parameter\\^";^" ^"second^ command^"` )
194+ t . ok ( fs . existsSync ( filename ) , 'script file was written' )
180195 cleanup ( )
181- t . not ( fs . existsSync ( args [ args . length - 1 ] ) , 'cleanup removes script file' )
196+ t . not ( fs . existsSync ( filename ) , 'cleanup removes script file' )
182197
183198 t . end ( )
184199 } )
@@ -194,7 +209,7 @@ if (isWindows) {
194209 args : [ '"quoted parameter";' , 'second command' ] ,
195210 } )
196211 t . equal ( shell , 'cmd' , 'default shell applies' )
197- t . match ( args , [ '/d' , '/s' , '/c' , / \. c m d $ / ] , 'got expected args' )
212+ t . match ( args , [ '/d' , '/s' , '/c' , / \. c m d \^ " $ / ] , 'got expected args' )
198213 t . match ( opts , {
199214 env : {
200215 npm_package_json : / p a c k a g e \. j s o n $ / ,
@@ -207,14 +222,15 @@ if (isWindows) {
207222 windowsVerbatimArguments : true ,
208223 } , 'got expected options' )
209224
210- const contents = fs . readFileSync ( args [ args . length - 1 ] , { encoding : 'utf8' } )
225+ const filename = unescapeCmd ( args [ args . length - 1 ] )
226+ const contents = fs . readFileSync ( filename , { encoding : 'utf8' } )
211227 t . equal ( contents , [
212228 '@echo off' ,
213- `script ^^^"\\^^^"quoted parameter\\^^^";^^^" ^^^"second command^^^"` ,
229+ `script ^^^"\\^^^"quoted^^^ parameter\\^^^";^^^" ^^^"second^^^ command^^^"` ,
214230 ] . join ( '\n' ) )
215- t . ok ( fs . existsSync ( args [ args . length - 1 ] ) , 'script file was written' )
231+ t . ok ( fs . existsSync ( filename ) , 'script file was written' )
216232 cleanup ( )
217- t . not ( fs . existsSync ( args [ args . length - 1 ] ) , 'cleanup removes script file' )
233+ t . not ( fs . existsSync ( filename ) , 'cleanup removes script file' )
218234
219235 t . end ( )
220236 } )
@@ -232,7 +248,7 @@ if (isWindows) {
232248 args : [ '"quoted parameter";' , 'second command' ] ,
233249 } )
234250 t . equal ( shell , 'cmd' , 'default shell applies' )
235- t . match ( args , [ '/d' , '/s' , '/c' , / \. c m d $ / ] , 'got expected args' )
251+ t . match ( args , [ '/d' , '/s' , '/c' , / \. c m d \^ " $ / ] , 'got expected args' )
236252 t . match ( opts , {
237253 env : {
238254 npm_package_json : / p a c k a g e \. j s o n $ / ,
@@ -245,15 +261,16 @@ if (isWindows) {
245261 windowsVerbatimArguments : true ,
246262 } , 'got expected options' )
247263
248- const contents = fs . readFileSync ( args [ args . length - 1 ] , { encoding : 'utf8' } )
264+ const filename = unescapeCmd ( args [ args . length - 1 ] )
265+ const contents = fs . readFileSync ( filename , { encoding : 'utf8' } )
249266 t . equal ( contents , [
250267 '@echo off' ,
251268 // eslint-disable-next-line max-len
252- `"my script" ^^^"\\^^^"quoted parameter\\^^^";^^^" ^^^"second command^^^"` ,
269+ `"my script" ^^^"\\^^^"quoted^^^ parameter\\^^^";^^^" ^^^"second^^^ command^^^"` ,
253270 ] . join ( '\n' ) )
254- t . ok ( fs . existsSync ( args [ args . length - 1 ] ) , 'script file was written' )
271+ t . ok ( fs . existsSync ( filename ) , 'script file was written' )
255272 cleanup ( )
256- t . not ( fs . existsSync ( args [ args . length - 1 ] ) , 'cleanup removes script file' )
273+ t . not ( fs . existsSync ( filename ) , 'cleanup removes script file' )
257274
258275 t . end ( )
259276 } )
@@ -275,7 +292,7 @@ if (isWindows) {
275292 args : [ '"quoted parameter";' , 'second command' ] ,
276293 } )
277294 t . equal ( shell , 'sh' , 'defaults to sh' )
278- t . match ( args , [ '-c' , / \. s h $ / ] , 'got expected args' )
295+ t . match ( args , [ '-c' , / \. s h ' $ / ] , 'got expected args' )
279296 t . match ( opts , {
280297 env : {
281298 npm_package_json : / p a c k a g e \. j s o n $ / ,
@@ -287,11 +304,12 @@ if (isWindows) {
287304 windowsVerbatimArguments : undefined ,
288305 } , 'got expected options' )
289306
290- const contents = fs . readFileSync ( args [ args . length - 1 ] , { encoding : 'utf8' } )
307+ const filename = unescapeSh ( args [ args . length - 1 ] )
308+ const contents = fs . readFileSync ( filename , { encoding : 'utf8' } )
291309 t . equal ( contents , `#!/usr/bin/env sh\nscript '"quoted parameter";' 'second command'` )
292- t . ok ( fs . existsSync ( args [ args . length - 1 ] ) , 'script file was written' )
310+ t . ok ( fs . existsSync ( filename ) , 'script file was written' )
293311 cleanup ( )
294- t . not ( fs . existsSync ( args [ args . length - 1 ] ) , 'cleanup removes script file' )
312+ t . not ( fs . existsSync ( filename ) , 'cleanup removes script file' )
295313
296314 t . end ( )
297315 } )
@@ -305,7 +323,7 @@ if (isWindows) {
305323 scriptShell : '/bin/sh' ,
306324 } )
307325 t . equal ( shell , '/bin/sh' , 'kept provided setting' )
308- t . match ( args , [ '-c' , / \. s h $ / ] , 'got expected args' )
326+ t . match ( args , [ '-c' , / \. s h ' $ / ] , 'got expected args' )
309327 t . match ( opts , {
310328 env : {
311329 npm_package_json : / p a c k a g e \. j s o n $ / ,
@@ -317,11 +335,12 @@ if (isWindows) {
317335 windowsVerbatimArguments : undefined ,
318336 } , 'got expected options' )
319337
320- const contents = fs . readFileSync ( args [ args . length - 1 ] , { encoding : 'utf8' } )
338+ const filename = unescapeSh ( args [ args . length - 1 ] )
339+ const contents = fs . readFileSync ( filename , { encoding : 'utf8' } )
321340 t . equal ( contents , `#!/bin/sh\nscript '"quoted parameter";' 'second command'` )
322- t . ok ( fs . existsSync ( args [ args . length - 1 ] ) , 'script file was written' )
341+ t . ok ( fs . existsSync ( filename ) , 'script file was written' )
323342 cleanup ( )
324- t . not ( fs . existsSync ( args [ args . length - 1 ] ) , 'cleanup removes script file' )
343+ t . not ( fs . existsSync ( filename ) , 'cleanup removes script file' )
325344
326345 t . end ( )
327346 } )
@@ -336,7 +355,7 @@ if (isWindows) {
336355 scriptShell : 'cmd.exe' ,
337356 } )
338357 t . equal ( shell , 'cmd.exe' , 'kept cmd.exe' )
339- t . match ( args , [ '/d' , '/s' , '/c' , / \. c m d $ / ] , 'got expected args' )
358+ t . match ( args , [ '/d' , '/s' , '/c' , / \. c m d \^ " $ / ] , 'got expected args' )
340359 t . match ( opts , {
341360 env : {
342361 npm_package_json : / p a c k a g e \. j s o n $ / ,
@@ -348,9 +367,10 @@ if (isWindows) {
348367 windowsVerbatimArguments : true ,
349368 } , 'got expected options' )
350369
351- t . ok ( fs . existsSync ( args [ args . length - 1 ] ) , 'script file was written' )
370+ const filename = unescapeCmd ( args [ args . length - 1 ] )
371+ t . ok ( fs . existsSync ( filename ) , 'script file was written' )
352372 cleanup ( )
353- t . not ( fs . existsSync ( args [ args . length - 1 ] ) , 'cleanup removes script file' )
373+ t . not ( fs . existsSync ( filename ) , 'cleanup removes script file' )
354374
355375 t . end ( )
356376 } )
0 commit comments