summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornimesh-msys <nimesh.patni@msystechnologies.com>2018-07-23 16:17:20 +0530
committernimesh-msys <nimesh.patni@msystechnologies.com>2018-07-23 17:27:13 +0530
commit4b5f73868ea131780ac29c3b8d6dfb7506b02afa (patch)
tree49e0308aa32cb62cfd3a3c50b925eaa41d0dbb62
parent1bd742d6833a27c685907c414c3bb9c16d543bdd (diff)
downloadchef-4b5f73868ea131780ac29c3b8d6dfb7506b02afa.tar.gz
Handling quotes in Windows Task commands
- Added a custom method to split the command and its arguments - Checked the beaviour when they are inclusive of single/double quotes - Added their specs to test the functionality. Covered a [tpec](https://github.com/chef/chef/compare/sp/7413) Fixes: MSYS-855 Signed-off-by: nimesh-msys <nimesh.patni@msystechnologies.com>
-rw-r--r--chef-config/lib/chef-config/path_helper.rb23
-rw-r--r--lib/chef/provider/windows_task.rb4
-rw-r--r--spec/functional/resource/windows_task_spec.rb32
3 files changed, 49 insertions, 10 deletions
diff --git a/chef-config/lib/chef-config/path_helper.rb b/chef-config/lib/chef-config/path_helper.rb
index 053c7a3c32..f1dc47a489 100644
--- a/chef-config/lib/chef-config/path_helper.rb
+++ b/chef-config/lib/chef-config/path_helper.rb
@@ -295,5 +295,28 @@ module ChefConfig
ChefConfig.logger.error("Cannot write to a SIP Path on OS X 10.11+")
false
end
+
+ # Splits a string into an array of tokens as commands and arguments
+ #
+ # str = 'command with "some arguments"'
+ # split_args(str) => ["command", "with", "\"some arguments\""]
+ #
+ def self.split_args(line)
+ cmd_args = []
+ field = ""
+ line.scan(/\s*(?>([^\s\\"]+|"([^"]*)"|'([^']*)')|(\S))(\s|\z)?/m) do |word, within_dq, within_sq, esc, sep|
+
+ # Appand the string with Word & Escape Character
+ field << (word || esc.gsub(/\\(.)/, '\\1'))
+
+ # Re-build the field when any whitespace character or
+ # End of string is encountered
+ if sep
+ cmd_args << field
+ field = ""
+ end
+ end
+ cmd_args
+ end
end
end
diff --git a/lib/chef/provider/windows_task.rb b/lib/chef/provider/windows_task.rb
index 4fb4817020..b1c59ec41c 100644
--- a/lib/chef/provider/windows_task.rb
+++ b/lib/chef/provider/windows_task.rb
@@ -21,6 +21,7 @@ require "rexml/document"
require "iso8601"
require "chef/mixin/powershell_out"
require "chef/provider"
+require "chef/util/path_helper"
require "win32/taskscheduler" if Chef::Platform.windows?
class Chef
@@ -229,8 +230,7 @@ class Chef
# seprated command arguments from :command property
def set_command_and_arguments
- new_resource.command = new_resource.command.gsub(/\\/, '\&\&')
- cmd, *args = Shellwords.split(new_resource.command)
+ cmd, *args = Chef::Util::PathHelper.split_args(new_resource.command)
new_resource.command = cmd
new_resource.command_arguments = args.join(" ")
end
diff --git a/spec/functional/resource/windows_task_spec.rb b/spec/functional/resource/windows_task_spec.rb
index 05f46d20ce..a4cee114f4 100644
--- a/spec/functional/resource/windows_task_spec.rb
+++ b/spec/functional/resource/windows_task_spec.rb
@@ -61,14 +61,14 @@ describe Chef::Resource::WindowsTask, :windows_only do
expect(subject).not_to be_updated_by_last_action
end
- it "creates scheduled task and sets command arguments" do
+ it "creates scheduled task and sets command arguments when arguments inclusive single quotes" do
subject.command "chef-client -W -L 'C:\\chef\\chef-ad-join.log'"
call_for_create_action
# loading current resource again to check new task is creted and it matches task parameters
current_resource = call_for_load_current_resource
expect(current_resource.exists).to eq(true)
expect(current_resource.task.application_name).to eq("chef-client")
- expect(current_resource.task.parameters).to eq("-W -L C:\\\\chef\\\\chef-ad-join.log")
+ expect(current_resource.task.parameters).to eq("-W -L 'C:\\chef\\chef-ad-join.log'")
end
it "does not converge the resource if it is already converged" do
@@ -79,20 +79,36 @@ describe Chef::Resource::WindowsTask, :windows_only do
expect(subject).not_to be_updated_by_last_action
end
- it "creates scheduled task and sets command arguments" do
- subject.command '"C:\\Program Files\\example\program.exe" -arg1 --arg2'
+ it "creates scheduled task and sets command arguments with spaces in command" do
+ subject.command '"C:\\Program Files\\example\\program.exe" -arg1 --arg2'
call_for_create_action
- # loading current resource again to check new task is creted and it matches task parameters
current_resource = call_for_load_current_resource
expect(current_resource.exists).to eq(true)
- expect(current_resource.task.application_name).to eq("C:\\Program Files\\example\\program.exe")
+ expect(current_resource.task.application_name).to eq('"C:\\Program Files\\example\\program.exe"')
expect(current_resource.task.parameters).to eq("-arg1 --arg2")
end
it "does not converge the resource if it is already converged" do
- subject.command '"C:\\Program Files\\example\program.exe" -arg1 --arg2'
+ subject.command '"C:\\Program Files\\example\\program.exe" -arg1 --arg2'
+ subject.run_action(:create)
+ subject.command '"C:\\Program Files\\example\\program.exe" -arg1 --arg2'
+ subject.run_action(:create)
+ expect(subject).not_to be_updated_by_last_action
+ end
+
+ it "creates scheduled task and sets command arguments with spaces in arguments" do
+ subject.command 'powershell.exe -file "C:\\Program Files\\app\\script.ps1"'
+ call_for_create_action
+ current_resource = call_for_load_current_resource
+ expect(current_resource.exists).to eq(true)
+ expect(current_resource.task.application_name).to eq("powershell.exe")
+ expect(current_resource.task.parameters).to eq('-file "C:\\Program Files\\app\\script.ps1"')
+ end
+
+ it "does not converge the resource if it is already converged" do
+ subject.command 'powershell.exe -file "C:\\Program Files\\app\\script.ps1"'
subject.run_action(:create)
- subject.command '"C:\\Program Files\\example\program.exe" -arg1 --arg2'
+ subject.command 'powershell.exe -file "C:\\Program Files\\app\\script.ps1"'
subject.run_action(:create)
expect(subject).not_to be_updated_by_last_action
end