Skip to content

Commit ddc1295

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 ddc1295

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: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,28 @@
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+
#scope = closure_scope
12+
if self['facts'] && self['facts']['kernel'] == 'windows'
13+
%("#{subject.gsub('"', '\\"')}")
14+
else
15+
subject.shellescape
16+
end
17+
end
18+
819
# Transforms a hash into a string of docker flags
920
newfunction(:docker_run_flags, type: :rvalue) do |args|
1021
opts = args[0] || {}
1122
flags = []
1223

1324
if opts['username']
14-
flags << "-u '#{opts['username'].shellescape}'"
25+
flags << "-u '#{call_function('docker::escape', [opts['username']])}'"
1526
end
1627

1728
if opts['hostname']
18-
flags << "-h '#{opts['hostname'].shellescape}'"
29+
flags << "-h '#{call_function('docker::escape', [opts['hostname']])}'"
1930
end
2031

2132
if opts['restart']
@@ -24,9 +35,9 @@ module Puppet::Parser::Functions
2435

2536
if opts['net']
2637
if opts['net'].is_a? String
27-
flags << "--net #{opts['net'].shellescape}"
38+
flags << "--net #{call_function('docker::escape', [opts['net']])}"
2839
elsif opts['net'].is_a? Array
29-
flags << "--net #{opts['net'].join(' --net ').shellescape}"
40+
flags << "--net #{call_function('docker::escape', [opts['net'].join(' --net ')])}" # FIXME: escaping is buggy
3041
end
3142
end
3243

@@ -72,7 +83,7 @@ module Puppet::Parser::Functions
7283

7384
multi_flags = ->(values, fmt) {
7485
filtered = [values].flatten.compact
75-
filtered.map { |val| (fmt + params_join_char) % val.shellescape }
86+
filtered.map { |val| (fmt + params_join_char) % call_function('docker::escape', [val]) }
7687
}
7788

7889
[

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

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,22 @@
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({'kernel' => kernel})
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(:kernel) { 'Linux' }
15+
16+
it 'escapes special chars' do
17+
expect(scope.function_docker_run_flags([{ 'env' => [%.MYSQL_PASSWORD='"$()[]{}<>.], 'extra_params' => [] }])).to match(/^-e MYSQL_PASSWORD\\=\\'\\"\\\$\\\(\\\)\\\[\\\]\\\{\\\}\\<\\> \\$/)
18+
end
19+
end
20+
21+
context "on windows" do
22+
let(:kernel) { 'windows' }
23+
it 'escapes special chars' do
24+
expect(scope.function_docker_run_flags([{ 'env' => [%.MYSQL_PASSWORD='"$()[]{}<>.], 'extra_params' => [] }])).to match(/^-e "MYSQL_PASSWORD='\\"\$\(\)\[\]\{\}<>" \\$/)
25+
end
1426
end
1527
end

0 commit comments

Comments
 (0)