Skip to content

Commit 2c5fb74

Browse files
committed
Merge pull request #127 from pstadler/sudo-escape-spaces
fix sudo command escaping
2 parents d9842c5 + 5d0cc93 commit 2c5fb74

File tree

4 files changed

+23
-17
lines changed

4 files changed

+23
-17
lines changed

lib/transport/index.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ var format = require('util').format
77
, errors = require('../errors')
88
, commands = require('./commands')
99
, queue = require('../utils/queue')
10-
, escapeSingleQuotes = require('../utils').escapeSingleQuotes;
10+
, escapeQuotes = require('../utils').escapeQuotes;
1111

1212
/**
1313
* A transport is the interface you use during flights. Basically they
@@ -190,8 +190,8 @@ Transport.prototype.sudo = function(command, options) {
190190
var user = options.user || 'root';
191191

192192
command = format('%s%s', this._execWith, command);
193-
command = escapeSingleQuotes(command);
194-
command = format("sudo -u %s -i bash -c '%s'", user, command);
193+
command = escapeQuotes(command);
194+
command = format("sudo -u %s -i bash -c \"'%s'\"", user, command);
195195

196196
return this._exec(command, options);
197197
};

lib/utils/index.js

+5-2
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,13 @@ exports.writeTempFile = function(str) {
1717
return fullpath;
1818
};
1919

20-
exports.escapeSingleQuotes = function(str) {
20+
exports.escapeQuotes = function(str) {
2121
if(!str) {
2222
return str;
2323
}
2424

25-
return str.replace(/'/g, "'\\''");
25+
str = str.replace(/"/g, '\\"');
26+
str = str.replace(/'/g, "'\\''");
27+
28+
return str;
2629
};

test/test.transport.js

+8-6
Original file line numberDiff line numberDiff line change
@@ -97,21 +97,23 @@ describe('transport', function() {
9797

9898
expect(transport._exec.calledOnce).to.be.true;
9999
expect(transport._exec.lastCall.args).to.deep.equal([
100-
"sudo -u root -i bash -c ''",
100+
"sudo -u root -i bash -c \"''\"",
101101
{}
102102
]);
103103
});
104104

105105
it('should properly escape the command', function() {
106106
transport._exec = sinon.stub();
107107

108-
transport.sudo('"cmd"');
108+
transport.sudo('printf "hello world"');
109109

110-
expect(transport._exec.lastCall.args[0]).to.equal("sudo -u root -i bash -c '\"cmd\"'");
110+
expect(transport._exec.lastCall.args[0])
111+
.to.equal("sudo -u root -i bash -c \"\'printf \\\"hello world\\\"\'\"");
111112

112-
transport.sudo("'cmd'");
113+
transport.sudo("printf 'hello world'");
113114

114-
expect(transport._exec.lastCall.args[0]).to.equal("sudo -u root -i bash -c ''\\''cmd'\\'''");
115+
expect(transport._exec.lastCall.args[0])
116+
.to.equal("sudo -u root -i bash -c \"'printf '\\''hello world'\\'''\"");
115117
});
116118

117119
it('should pass options to #_exec()', function() {
@@ -127,7 +129,7 @@ describe('transport', function() {
127129

128130
transport.sudo('cmd', { user: 'not-root' });
129131

130-
expect(transport._exec.lastCall.args[0]).to.equal("sudo -u not-root -i bash -c 'cmd'");
132+
expect(transport._exec.lastCall.args[0]).to.equal("sudo -u not-root -i bash -c \"'cmd'\"");
131133
});
132134
});
133135

test/test.utils.js

+7-6
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,15 @@ describe('utils', function() {
3737
});
3838
});
3939

40-
describe('#escapeSingleQuotes()', function() {
40+
describe('#escapeQuotes()', function() {
4141
it('should correctly escape single quotes', function() {
42-
var escapeSingleQuotes = proxyquire('../lib/utils', {}).escapeSingleQuotes;
42+
var escapeQuotes = proxyquire('../lib/utils', {}).escapeQuotes;
4343

44-
expect(escapeSingleQuotes("'string'")).to.equal("'\\''string'\\''");
45-
expect(escapeSingleQuotes('"string"')).to.equal('"string"');
46-
expect(escapeSingleQuotes("\\'string\\'")).to.equal("\\'\\''string\\'\\''");
47-
expect(escapeSingleQuotes('')).to.equal('');
44+
expect(escapeQuotes("'string'")).to.equal("'\\''string'\\''");
45+
expect(escapeQuotes('"string"')).to.equal('\\"string\\"');
46+
expect(escapeQuotes("\\'string\\'")).to.equal("\\'\\''string\\'\\''");
47+
expect(escapeQuotes('')).to.equal('');
48+
expect(escapeQuotes()).to.be.undefined;
4849
});
4950
});
5051

0 commit comments

Comments
 (0)