Skip to content

Commit 4c37e04

Browse files
committed
Work around quoted batch file names
Fix: #10 Read %~dp0 in a subroutine, so that it does not get an incorrect value when the command name is quoted. While we're at it, bring this module up to 100% test coverage, and fix a few obvious bugs that full coverage uncovered. BREAKING CHANGE: This requires an update to read-cmd-shim, because the format of the command invocation changed, and it reads that out of the generated batch script.
1 parent 9cc5388 commit 4c37e04

File tree

6 files changed

+570
-277
lines changed

6 files changed

+570
-277
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,5 @@ results
1414
npm-debug.log
1515

1616
node_modules
17+
/coverage
18+
/.nyc_output

index.js

+35-17
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
// "#!<prog> <args...>"
77
//
88
// Write a binroot/pkg.bin + ".cmd" file that has this line in it:
9-
// @<prog> <args...> %~dp0<target> %*
9+
// @<prog> <args...> %dp0%<target> %*
1010

1111
module.exports = cmdShim
1212
cmdShim.ifExists = cmdShimIfExists
@@ -43,9 +43,10 @@ function cmdShim (from, to, cb) {
4343
}
4444

4545
function cmdShim_ (from, to, cb) {
46-
var then = times(2, next, cb)
46+
var then = times(3, next, cb)
4747
rm(to, then)
4848
rm(to + ".cmd", then)
49+
rm(to + ".ps1", then)
4950

5051
function next(er) {
5152
writeShim(from, to, cb)
@@ -61,7 +62,7 @@ function writeShim (from, to, cb) {
6162
if (er)
6263
return cb(er)
6364
fs.readFile(from, "utf8", function (er, data) {
64-
if (er) return writeShim_(from, to, null, null, cb)
65+
if (er) return writeShim_(from, to, null, null, null, cb)
6566
var firstLine = data.trim().split(/\r*\n/)[0]
6667
, shebang = firstLine.match(shebangExpr)
6768
if (!shebang) return writeShim_(from, to, null, null, null, cb)
@@ -86,50 +87,67 @@ function writeShim_ (from, to, prog, args, variables, cb) {
8687
args = args || ""
8788
variables = variables || ""
8889
if (!prog) {
89-
prog = "\"%~dp0\\" + target + "\""
90+
prog = "\"%dp0%\\" + target + "\""
9091
shProg = "\"$basedir/" + shTarget + "\""
9192
pwshProg = shProg
9293
args = ""
9394
target = ""
9495
shTarget = ""
9596
} else {
96-
longProg = "\"%~dp0\\" + prog + ".exe\""
97+
longProg = "\"%dp0%\\" + prog + ".exe\""
9798
shLongProg = "\"$basedir/" + prog + "\""
9899
pwshLongProg = "\"$basedir/" + prog + "$exe\""
99-
target = "\"%~dp0\\" + target + "\""
100+
target = "\"%dp0%\\" + target + "\""
100101
shTarget = "\"$basedir/" + shTarget + "\""
101102
}
102103

103104
// @SETLOCAL
105+
// @CALL :find_dp0
104106
//
105-
// @IF EXIST "%~dp0\node.exe" (
106-
// @SET "_prog=%~dp0\node.exe"
107+
// @IF EXIST "%dp0%\node.exe" (
108+
// @SET "_prog=%dp0%\node.exe"
107109
// ) ELSE (
108110
// @SET "_prog=node"
109111
// @SET PATHEXT=%PATHEXT:;.JS;=;%
110112
// )
111113
//
112-
// "%_prog%" "%~dp0\.\node_modules\npm\bin\npm-cli.js" %*
114+
// "%_prog%" "%dp0%\.\node_modules\npm\bin\npm-cli.js" %*
113115
// @ENDLOCAL
116+
// @EXIT /b
117+
//
118+
// :find_dp0
119+
// SET dp0=%~dp0
120+
// EXIT /b
121+
//
122+
// Subroutine trick to fix https://github.com/npm/cmd-shim/issues/10
123+
var head = '@ECHO off\r\n' +
124+
'SETLOCAL\r\n' +
125+
'CALL find_dp0\r\n'
126+
var foot = 'ENDLOCAL\r\n' +
127+
'EXIT /b\r\n' +
128+
'find_dp0:\r\n' +
129+
'SET dp0=%~dp0\r\n' +
130+
'EXIT /b\r\n'
131+
114132
var cmd
115133
if (longProg) {
116134
shLongProg = shLongProg.trim();
117135
args = args.trim();
118136
var variableDeclarationsAsBatch = toBatchSyntax.convertToSetCommands(variables)
119-
cmd = "@SETLOCAL\r\n"
137+
cmd = head
120138
+ variableDeclarationsAsBatch
121139
+ "\r\n"
122-
+ "@IF EXIST " + longProg + " (\r\n"
123-
+ " @SET \"_prog=" + longProg.replace(/(^")|("$)/g, '') + "\"\r\n"
140+
+ "IF EXIST " + longProg + " (\r\n"
141+
+ " SET \"_prog=" + longProg.replace(/(^")|("$)/g, '') + "\"\r\n"
124142
+ ") ELSE (\r\n"
125-
+ " @SET \"_prog=" + prog.replace(/(^")|("$)/g, '') + "\"\r\n"
126-
+ " @SET PATHEXT=%PATHEXT:;.JS;=;%\r\n"
143+
+ " SET \"_prog=" + prog.replace(/(^")|("$)/g, '') + "\"\r\n"
144+
+ " SET PATHEXT=%PATHEXT:;.JS;=;%\r\n"
127145
+ ")\r\n"
128146
+ "\r\n"
129147
+ "\"%_prog%\" " + args + " " + target + " %*\r\n"
130-
+ '@ENDLOCAL\r\n'
148+
+ foot
131149
} else {
132-
cmd = "@" + prog + " " + args + " " + target + " %*\r\n"
150+
cmd = head + prog + " " + args + " " + target + " %*\r\n" + foot
133151
}
134152

135153
// #!/bin/sh
@@ -228,7 +246,7 @@ function writeShim_ (from, to, prog, args, variables, cb) {
228246
}
229247

230248
function chmodShim (to, cb) {
231-
var then = times(2, cb, cb)
249+
var then = times(3, cb, cb)
232250
fs.chmod(to, "0755", then)
233251
fs.chmod(to + ".cmd", "0755", then)
234252
fs.chmod(to + ".ps1", "0755", then)

lib/to-batch-syntax.js

-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ function replaceDollarWithPercentPair(value) {
3636
var dollarExpressions = /\$\{?([^\$@#\?\- \t{}:]+)\}?/g
3737
var result = ""
3838
var startIndex = 0
39-
value = value || ""
4039
do {
4140
var match = dollarExpressions.exec(value)
4241
if(match) {

package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
"version": "2.1.0",
44
"description": "Used in npm for command line application support",
55
"scripts": {
6-
"test": "tap test/*.js"
6+
"test": "tap test/*.js --100",
7+
"snap": "TAP_SNAPSHOT=1 tap test/*.js --100"
78
},
89
"repository": {
910
"type": "git",

0 commit comments

Comments
 (0)