Split with shellwords and quote paths in command filter

This uses shellwords to split the command in the command filter
inside the winrm communicator. Using shellwords properly handles
things like quoted paths. Path arguments are also quoted to
prevent issues with paths that include spaces.

Fixes #9390
This commit is contained in:
Chris Roberts 2018-04-09 16:52:53 -07:00
parent be1beb80a4
commit ddfd86f3d1
5 changed files with 30 additions and 16 deletions

View File

@ -1,3 +1,5 @@
require "shellwords"
module VagrantPlugins
module CommunicatorWinRM
module CommandFilters
@ -6,14 +8,14 @@ module VagrantPlugins
def filter(command)
# mkdir -p /some/dir
# mkdir /some/dir
cmd_parts = command.strip.split(/\s+/)
cmd_parts = Shellwords.split(command.strip)
dir = cmd_parts.pop
while !dir.nil? && dir.start_with?('-')
dir = cmd_parts.pop
end
# This will ignore any -p switches, which are redundant in PowerShell,
# and ambiguous in PowerShell 4+
return "mkdir #{dir} -force"
return "mkdir \"#{dir}\" -force"
end
def accept?(command)

View File

@ -1,3 +1,5 @@
require "shellwords"
module VagrantPlugins
module CommunicatorWinRM
module CommandFilters
@ -9,7 +11,7 @@ module VagrantPlugins
# rm -R -f /some/dir
# rm -f /some/dir
# rm /some/dir
cmd_parts = command.strip.split(/\s+/)
cmd_parts = Shellwords.split(command.strip)
# Figure out if we need to do this recursively
recurse = false
@ -29,9 +31,9 @@ module VagrantPlugins
ret_cmd = ''
if recurse
ret_cmd = "rm #{dir} -recurse -force"
ret_cmd = "rm \"#{dir}\" -recurse -force"
else
ret_cmd = "rm #{dir} -force"
ret_cmd = "rm \"#{dir}\" -force"
end
return ret_cmd
end

View File

@ -1,3 +1,5 @@
require "shellwords"
module VagrantPlugins
module CommunicatorWinRM
module CommandFilters
@ -9,7 +11,7 @@ module VagrantPlugins
# test -L /somelink
# test -x /tmp/some.exe
cmd_parts = command.strip.split(/\s+/)
cmd_parts = Shellwords.split(command.strip)
flag = cmd_parts[1]
path = cmd_parts[2]

View File

@ -1,12 +1,14 @@
require "shellwords"
module VagrantPlugins
module CommunicatorWinRM
module CommandFilters
# Converts a *nix 'which' command to a PowerShell equivalent
class Which
def filter(command)
executable = command.strip.split(/\s+/)[1]
executable = Shellwords.split(command.strip)[1]
return <<-EOH
$command = [Array](Get-Command #{executable} -errorAction SilentlyContinue)
$command = [Array](Get-Command "#{executable}" -errorAction SilentlyContinue)
if ($null -eq $command) { exit 1 }
write-host $command[0].Definition
exit 0

View File

@ -21,7 +21,7 @@ describe VagrantPlugins::CommunicatorWinRM::CommandFilter, unit: true do
it 'filters out which commands' do
expect(subject.filter('which ruby')).to include(
'[Array](Get-Command ruby -errorAction SilentlyContinue)')
'[Array](Get-Command "ruby" -errorAction SilentlyContinue)')
end
it 'filters out test -d commands' do
@ -54,25 +54,31 @@ describe VagrantPlugins::CommunicatorWinRM::CommandFilter, unit: true do
it 'filters out rm recurse commands' do
expect(subject.filter('rm -Rf /some/dir')).to eq(
"rm /some/dir -recurse -force")
"rm \"/some/dir\" -recurse -force")
expect(subject.filter('rm -fr /some/dir')).to eq(
"rm /some/dir -recurse -force")
"rm \"/some/dir\" -recurse -force")
expect(subject.filter('rm -r /some/dir')).to eq(
"rm /some/dir -recurse -force")
"rm \"/some/dir\" -recurse -force")
expect(subject.filter('rm -r "/some/dir"')).to eq(
"rm \"/some/dir\" -recurse -force")
end
it 'filters out rm commands' do
expect(subject.filter('rm /some/dir')).to eq(
"rm /some/dir -force")
"rm \"/some/dir\" -force")
expect(subject.filter('rm -f /some/dir')).to eq(
"rm /some/dir -force")
"rm \"/some/dir\" -force")
expect(subject.filter('rm -f "/some/dir"')).to eq(
"rm \"/some/dir\" -force")
end
it 'filters out mkdir commands' do
expect(subject.filter('mkdir /some/dir')).to eq(
"mkdir /some/dir -force")
"mkdir \"/some/dir\" -force")
expect(subject.filter('mkdir -p /some/dir')).to eq(
"mkdir /some/dir -force")
"mkdir \"/some/dir\" -force")
expect(subject.filter('mkdir "/some/dir"')).to eq(
"mkdir \"/some/dir\" -force")
end
it 'filters out chown commands' do