From dd15137e41f0715ad6b013b41319f54f128097af Mon Sep 17 00:00:00 2001 From: Jay Adkisson Date: Sat, 3 Jul 2010 13:15:59 +0800 Subject: [PATCH] escape quotes for bash, furrealz this time Any parameter in a job type template which is surrounded by quotes will now be auto-escaped. Examples: job_type :foo, :template => "/my/cool/bin ':bar'" every :day do foo %(single quote! -> ' <-) end will render to @daily /my/cool/bin 'single quote! -> '\'' <-' --- lib/whenever/job.rb | 27 ++++++++++++++++++--------- lib/whenever/job_types/default.rb | 6 +++--- test/job_test.rb | 20 +++++++++++++------- test/output_at_test.rb | 6 +++--- test/output_runner_test.rb | 24 ++++++++++++------------ 5 files changed, 49 insertions(+), 34 deletions(-) diff --git a/lib/whenever/job.rb b/lib/whenever/job.rb index 6f095d6..5b3dfb2 100644 --- a/lib/whenever/job.rb +++ b/lib/whenever/job.rb @@ -16,25 +16,34 @@ module Whenever template = @options[:template].dup template.gsub(/:\w+/) do |key| - if key == ':task' && template.index("':task'") - escape_single_quotes(@options[:task]) - elsif key == ':task' && template.index('":task"') - escape_double_quotes(@options[:task]) + + single_quote = "'" + double_quote = '"' + + char_before = $`[-1..-1] + char_after = $'[0..0] + + option = @options[key.sub(':', '').to_sym] + + if char_before == single_quote && char_after == single_quote + escape_single_quotes(option) + elsif char_after == double_quote && char_after == double_quote + escape_double_quotes(option) else - @options[key.sub(':', '').to_sym] + option end end end protected - + def escape_single_quotes(str) - str.gsub(/'/, %q('\'')) + str.gsub(/'/) { "'\\''" } end def escape_double_quotes(str) - str.gsub(/"/, %q(\")) + str.gsub(/"/) { '\"' } end end -end \ No newline at end of file +end diff --git a/lib/whenever/job_types/default.rb b/lib/whenever/job_types/default.rb index 2eaf56e..2a918dd 100644 --- a/lib/whenever/job_types/default.rb +++ b/lib/whenever/job_types/default.rb @@ -1,3 +1,3 @@ -job_type :command, ':task' -job_type :runner, 'cd :path && script/runner -e :environment ":task"' -job_type :rake, 'cd :path && RAILS_ENV=:environment /usr/bin/env rake :task' \ No newline at end of file +job_type :command, %(:task) +job_type :runner, %(cd :path && script/runner -e :environment ':task') +job_type :rake, %(cd :path && RAILS_ENV=:environment /usr/bin/env rake :task) diff --git a/test/job_test.rb b/test/job_test.rb index 8cda6af..cd878aa 100644 --- a/test/job_test.rb +++ b/test/job_test.rb @@ -18,14 +18,20 @@ class JobTest < Test::Unit::TestCase assert_equal %q("abc123"), job.output end - should "output escaped single quotes in :task when it's wrapped in them" do - job = new_job(:template => "outside ':task' outside", :task => "'inside'") - assert_equal %q(outside ''\''inside'\''' outside), job.output + should "output escaped single quotes in when it's wrapped in them" do + job = new_job( + :template => "before ':foo' after", + :foo => "quote -> ' <- quote" + ) + assert_equal %q(before 'quote -> '\'' <- quote' after), job.output end - should "output escaped double quotes in :task when it's wrapped in them" do - job = new_job(:template => 'outside ":task" outside', :task => '"inside"') - assert_equal %q(outside "\"inside"\" outside), job.output + should "output escaped double quotes when it's wrapped in them" do + job = new_job( + :template => 'before ":foo" after', + :foo => 'quote -> " <- quote' + ) + assert_equal %q(before "quote -> \" <- quote" after), job.output end end @@ -35,4 +41,4 @@ private Whenever::Job.new(options) end -end \ No newline at end of file +end diff --git a/test/output_at_test.rb b/test/output_at_test.rb index 8131b28..95ce0bf 100644 --- a/test/output_at_test.rb +++ b/test/output_at_test.rb @@ -91,7 +91,7 @@ class OutputAtTest < Test::Unit::TestCase end should "output the runner using one entry because the times are aligned" do - assert_match '2 5,15 * * 1,3,5 cd /your/path && script/runner -e production "blahblah"', @output + assert_match %(2 5,15 * * 1,3,5 cd /your/path && script/runner -e production 'blahblah'), @output end end @@ -168,9 +168,9 @@ class OutputAtTest < Test::Unit::TestCase should "output all of the commands @daily" do assert_match '@daily cd /your/path && RAILS_ENV=production /usr/bin/env rake blah:blah', @output - assert_match '@daily cd /your/path && script/runner -e production "runner_1"', @output + assert_match %(@daily cd /your/path && script/runner -e production 'runner_1'), @output assert_match '@daily command_1', @output - assert_match '@daily cd /your/path && script/runner -e production "runner_2"', @output + assert_match %(@daily cd /your/path && script/runner -e production 'runner_2'), @output assert_match '@daily command_2', @output end end diff --git a/test/output_runner_test.rb b/test/output_runner_test.rb index 9bb1411..de61012 100644 --- a/test/output_runner_test.rb +++ b/test/output_runner_test.rb @@ -8,13 +8,13 @@ class OutputRunnerTest < Test::Unit::TestCase <<-file set :path, '/my/path' every 2.hours do - runner "blahblah" + runner 'blahblah' end file end should "output the runner using that path" do - assert_match two_hours + ' cd /my/path && script/runner -e production "blahblah"', @output + assert_match two_hours + %( cd /my/path && script/runner -e production 'blahblah'), @output end end @@ -30,7 +30,7 @@ class OutputRunnerTest < Test::Unit::TestCase end should "output the runner using that path" do - assert_match two_hours + ' cd /some/other/path && script/runner -e production "blahblah"', @output + assert_match two_hours + %( cd /some/other/path && script/runner -e production 'blahblah'), @output end end @@ -41,13 +41,13 @@ class OutputRunnerTest < Test::Unit::TestCase @output = Whenever.cron \ <<-file every 2.hours do - runner "blahblah" + runner 'blahblah' end file end should "output the runner using that path" do - assert_match two_hours + ' cd /my/path && script/runner -e production "blahblah"', @output + assert_match two_hours + %( cd /my/path && script/runner -e production 'blahblah'), @output end end @@ -65,7 +65,7 @@ class OutputRunnerTest < Test::Unit::TestCase end should "use the path" do - assert_match two_hours + ' cd /my/path && script/runner -e production "blahblah"', @output + assert_match two_hours + %( cd /my/path && script/runner -e production 'blahblah'), @output assert_no_match /\/rails\/path/, @output end end @@ -83,7 +83,7 @@ class OutputRunnerTest < Test::Unit::TestCase end should "output the runner using that environment" do - assert_match two_hours + ' cd /my/path && script/runner -e silly "blahblah"', @output + assert_match two_hours + %( cd /my/path && script/runner -e silly 'blahblah'), @output end end @@ -100,7 +100,7 @@ class OutputRunnerTest < Test::Unit::TestCase end should "output the runner using that environment" do - assert_match two_hours + ' cd /my/path && script/runner -e serious "blahblah"', @output + assert_match two_hours + %( cd /my/path && script/runner -e serious 'blahblah'), @output end end @@ -117,7 +117,7 @@ class OutputRunnerTest < Test::Unit::TestCase end should "output the runner using the override environment" do - assert_match two_hours + ' cd /my/path && script/runner -e serious "blahblah"', @output + assert_match two_hours + %( cd /my/path && script/runner -e serious 'blahblah'), @output end end @@ -134,7 +134,7 @@ class OutputRunnerTest < Test::Unit::TestCase end should "output the runner using the overridden path and environment" do - assert_match two_hours + ' cd /serious/path && script/runner -e serious "blahblah"', @output + assert_match two_hours + %( cd /serious/path && script/runner -e serious 'blahblah'), @output end end @@ -151,7 +151,7 @@ class OutputRunnerTest < Test::Unit::TestCase end should "output the runner using the overridden path and environment" do - assert_match two_hours + ' cd /serious/path && script/runner -e serious "blahblah"', @output + assert_match two_hours + %( cd /serious/path && script/runner -e serious 'blahblah'), @output end end @@ -168,7 +168,7 @@ class OutputRunnerTest < Test::Unit::TestCase end should "output the runner using the original environmnet" do - assert_match two_hours + ' cd /silly/path && script/runner -e silly "blahblah"', @output + assert_match two_hours + %( cd /silly/path && script/runner -e silly 'blahblah'), @output end end