Skip to content

Commit 52eb180

Browse files
committed
Attempt to escape things in on OS dependant way
Ruby Shellwords#shellescape "Escapes a string so that it can be safely used in a Bourne shell command line". This is fine for a UNIX like operating system, but windows does not complies with this. Attempt to fix CI by manually "escaping" strings on windows (i.e. quote them and escape quotes with a backslash), and relying on shellescape for other operating systems.
1 parent 3713bc8 commit 52eb180

File tree

2 files changed

+30
-7
lines changed

2 files changed

+30
-7
lines changed

lib/puppet/parser/functions/docker_run_flags.rb

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,27 @@
55
# docker_run_flags.rb
66
#
77
module Puppet::Parser::Functions
8+
newfunction(:'docker::escape', type: :rvalue) do |args|
9+
subject = args[0]
10+
11+
if self['facts'] && self['facts']['os']['family'] == 'windows'
12+
%("#{subject.gsub('"', '\\"')}")
13+
else
14+
subject.shellescape
15+
end
16+
end
17+
818
# Transforms a hash into a string of docker flags
919
newfunction(:docker_run_flags, type: :rvalue) do |args|
1020
opts = args[0] || {}
1121
flags = []
1222

1323
if opts['username']
14-
flags << "-u '#{opts['username'].shellescape}'"
24+
flags << "-u '#{call_function('docker::escape', [opts['username']])}'"
1525
end
1626

1727
if opts['hostname']
18-
flags << "-h '#{opts['hostname'].shellescape}'"
28+
flags << "-h '#{call_function('docker::escape', [opts['hostname']])}'"
1929
end
2030

2131
if opts['restart']
@@ -24,9 +34,9 @@ module Puppet::Parser::Functions
2434

2535
if opts['net']
2636
if opts['net'].is_a? String
27-
flags << "--net #{opts['net'].shellescape}"
37+
flags << "--net #{call_function('docker::escape', [opts['net']])}"
2838
elsif opts['net'].is_a? Array
29-
flags << "--net #{opts['net'].join(' --net ').shellescape}"
39+
flags << "--net #{call_function('docker::escape', [opts['net'].join(' --net ')])}" # FIXME: escaping is buggy
3040
end
3141
end
3242

@@ -72,7 +82,7 @@ module Puppet::Parser::Functions
7282

7383
multi_flags = ->(values, fmt) {
7484
filtered = [values].flatten.compact
75-
filtered.map { |val| (fmt + params_join_char) % val.shellescape }
85+
filtered.map { |val| (fmt + params_join_char) % call_function('docker::escape', [val]) }
7686
}
7787

7888
[

spec/unit/lib/puppet/parser/functions/docker_run_flags_spec.rb

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,23 @@
66
compiler = Puppet::Parser::Compiler.new(node)
77
scope = Puppet::Parser::Scope.new(compiler)
88
allow(scope).to receive(:environment).and_return(nil)
9+
allow(scope).to receive(:[]).with('facts').and_return({ 'os' => { 'family' => os_family } })
910
scope
1011
end
1112

12-
it 'env with special chars' do
13-
expect(scope.function_docker_run_flags([{ 'env' => [%.MYSQL_PASSWORD='"$()[]{}<>.], 'extra_params' => [] }])).to match(/^-e MYSQL_PASSWORD\\=\\'\\"\\\$\\\(\\\)\\\[\\\]\\\{\\\}\\<\\> \\$/)
13+
context 'on POSIX system' do
14+
let(:os_family) { 'Linux' }
15+
16+
it 'escapes special chars' do
17+
expect(scope.function_docker_run_flags([{ 'env' => [%.MYSQL_PASSWORD='"$()[]{}<>.], 'extra_params' => [] }])).to eq(%(-e MYSQL_PASSWORD\\=\\'\\"\\$\\(\\)\\[\\]\\{\\}\\<\\> \\\n))
18+
end
19+
end
20+
21+
context 'on windows' do
22+
let(:os_family) { 'windows' }
23+
24+
it 'escapes special chars' do
25+
expect(scope.function_docker_run_flags([{ 'env' => [%.MYSQL_PASSWORD='"$()[]{}<>.], 'extra_params' => [] }])).to eq(%^-e "MYSQL_PASSWORD='\\"$()[]{}<>" \\\n^)
26+
end
1427
end
1528
end

0 commit comments

Comments
 (0)