sidekiq 2.16.0 → 2.16.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of sidekiq might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 08f16a145d63e3e2a04ec513885c855f1a0b12d7
4
- data.tar.gz: 5596a8f758154a052f1b0e2eedfbe837bc801f2e
3
+ metadata.gz: 34e9d5b007bd144d33930ee67fa26a492e6664eb
4
+ data.tar.gz: 28e8782a74a452e75040674eaf22ac33cf2bb660
5
5
  SHA512:
6
- metadata.gz: 5867e076904084e5b63c9f7a3dbe9358173405b48c3903954d7cf75129d2afe7d92aac884da37fa492d4542e82233d867d9927c3467e4cd11496abc123a965cc
7
- data.tar.gz: fe962090ddb489623737ccc89279f6cd2bf9e36d53dadcc9a7fdd9f41bca067e1743d04a98ce5afe49c83f3e467819695221ac8bd5338bbb5b2f89c9294d6afe
6
+ metadata.gz: a0c318ac705b8ca596327765b1ea1ed914534b70736dc3af10c8adac268d53f576e30df7b4a56568fd8b5f97e1f4e739609af50fc03ccf83d730f1a8c9bfcfd7
7
+ data.tar.gz: bc670c8eb9e5d31fe24d4d7a7ef7301e8390d606c178c6b68b9638b8588f298c63c97d500280ddf802f69b602a589ca2d913f7336338ac00a2582fecec4ae58b
data/Changes.md CHANGED
@@ -1,3 +1,10 @@
1
+ 2.16.1
2
+ -----------
3
+
4
+ - Revert usage of `resolv-replace`. MRI's native DNS lookup releases the GIL.
5
+ - Fix several Capistrano 3 issues
6
+ - Escaping dynamic data like job args and error messages in Sidekiq Web UI. [#1299, lian]
7
+
1
8
  2.16.0
2
9
  -----------
3
10
 
@@ -1,4 +1,4 @@
1
- if Gem::Version.new(Capistrano::VERSION).release >= Gem::Version.new('3.0.0')
1
+ if defined?(Capistrano::VERSION) && Gem::Version.new(Capistrano::VERSION).release >= Gem::Version.new('3.0.0')
2
2
  load File.expand_path("../tasks/sidekiq.rake", __FILE__)
3
3
  else
4
4
  require_relative 'capistrano2'
@@ -1,6 +1,5 @@
1
1
  $stdout.sync = true
2
2
 
3
- require 'resolv-replace'
4
3
  require 'yaml'
5
4
  require 'singleton'
6
5
  require 'optparse'
@@ -1,8 +1,10 @@
1
1
  namespace :load do
2
2
  task :defaults do
3
3
 
4
+ set :sidekiq_default_hooks, ->{ true }
5
+
4
6
  # If you need a special boot commands
5
- #
7
+ #
6
8
  # set :sidekiq_cmd, ->{ "bundle exec sidekiq" }
7
9
  # set :sidekiqctl_cmd, ->{ "bundle exec sidekiqctl" }
8
10
  set :sidekiq_cmd, ->{ }
@@ -31,9 +33,9 @@ namespace :sidekiq do
31
33
  desc "Quiet sidekiq (stop accepting new work)"
32
34
  task :quiet do
33
35
  on roles fetch(:sidekiq_role) do
34
- within current_path do
35
- for_each_process do |pid_file, idx|
36
- if test "[ -f #{current_path}/#{pid_file} ]"
36
+ for_each_process do |pid_file, idx|
37
+ if test "[ -f #{current_path}/#{pid_file} ]"
38
+ within current_path do
37
39
  if fetch(:sidekiqctl_cmd)
38
40
  execute fetch(:sidekiqctl_cmd), 'quiet', "#{current_path}/#{pid_file}"
39
41
  else
@@ -48,9 +50,9 @@ namespace :sidekiq do
48
50
  desc "Stop sidekiq"
49
51
  task :stop do
50
52
  on roles fetch(:sidekiq_role) do
51
- within current_path do
52
- for_each_process do |pid_file, idx|
53
- if test "[ -f #{current_path}/#{pid_file} ]"
53
+ for_each_process do |pid_file, idx|
54
+ if test "[ -f #{current_path}/#{pid_file} ]"
55
+ within current_path do
54
56
  if fetch(:sidekiqctl_cmd)
55
57
  execute fetch(:sidekiqctl_cmd), 'stop', "#{current_path}/#{pid_file}", fetch(:sidekiq_timeout)
56
58
  else
@@ -69,9 +71,9 @@ namespace :sidekiq do
69
71
  within current_path do
70
72
  for_each_process do |pid_file, idx|
71
73
  if fetch(:sidekiq_cmd)
72
- execute fetch(:sidekiq_cmd), "-d -i #{idx} -P #{pid_file} #{fetch(:sidekiq_options)}"
74
+ execute fetch(:sidekiq_cmd), "-d -i #{idx} -P #{pid_file} #{fetch(:sidekiq_options)}"
73
75
  else
74
- execute :bundle, :exec, :sidekiq, "-d -i #{idx} -P #{pid_file} #{fetch(:sidekiq_options)}"
76
+ execute :bundle, :exec, :sidekiq, "-d -i #{idx} -P #{pid_file} #{fetch(:sidekiq_options)}"
75
77
  end
76
78
  end
77
79
  end
@@ -84,9 +86,11 @@ namespace :sidekiq do
84
86
  invoke 'sidekiq:start'
85
87
  end
86
88
 
87
- after 'deploy:starting', 'sidekiq:quiet'
88
- after 'deploy:updated', 'sidekiq:stop'
89
- after 'deploy:reverted', 'sidekiq:stop'
90
- after 'deploy:published', 'sidekiq:start'
91
-
89
+ if fetch(:sidekiq_default_hooks)
90
+ after 'deploy:starting', 'sidekiq:quiet'
91
+ after 'deploy:updated', 'sidekiq:stop'
92
+ after 'deploy:reverted', 'sidekiq:stop'
93
+ after 'deploy:published', 'sidekiq:start'
94
+ end
95
+
92
96
  end
@@ -1,3 +1,3 @@
1
1
  module Sidekiq
2
- VERSION = "2.16.0"
2
+ VERSION = "2.16.1"
3
3
  end
@@ -127,7 +127,7 @@ module Sidekiq
127
127
  def display_args(args, truncate_after_chars = 2000)
128
128
  args.map do |arg|
129
129
  a = arg.inspect
130
- truncate(a)
130
+ h(truncate(a))
131
131
  end.join(", ")
132
132
  end
133
133
 
@@ -159,7 +159,7 @@ module Sidekiq
159
159
  end
160
160
 
161
161
  def h(text)
162
- ERB::Util.h(text)
162
+ Rack::Utils.escape_html(text)
163
163
  end
164
164
 
165
165
  # Any paginated list that performs an action needs to redirect
@@ -265,6 +265,47 @@ class TestWeb < Sidekiq::Test
265
265
  assert_match /#{msg['args'][2]}/, last_response.body
266
266
  end
267
267
 
268
+ it 'escape job args and error messages' do
269
+ # on /retries page
270
+ params = add_xss_retry
271
+ get '/retries'
272
+ assert_equal 200, last_response.status
273
+ assert_match /FailWorker/, last_response.body
274
+
275
+ assert last_response.body.include?( "fail message: &lt;a&gt;hello&lt;&#x2F;a&gt;" )
276
+ assert !last_response.body.include?( "fail message: <a>hello</a>" )
277
+
278
+ assert last_response.body.include?( "args\">&quot;&lt;a&gt;hello&lt;&#x2F;a&gt;&quot;<" )
279
+ assert !last_response.body.include?( "args\"><a>hello</a><" )
280
+
281
+
282
+ # on /workers page
283
+ Sidekiq.redis do |conn|
284
+ identity = 'foo:1234-123abc:default'
285
+ conn.sadd('workers', identity)
286
+ conn.setex("worker:#{identity}:started", 10, Time.now.to_s)
287
+ hash = {:queue => 'critical', :payload => { 'class' => "FailWorker", 'args' => ["<a>hello</a>"] }, :run_at => Time.now.to_i }
288
+ conn.setex("worker:#{identity}", 10, Sidekiq.dump_json(hash))
289
+ end
290
+
291
+ get '/workers'
292
+ assert_equal 200, last_response.status
293
+ assert_match /FailWorker/, last_response.body
294
+ assert last_response.body.include?( "&lt;a&gt;hello&lt;&#x2F;a&gt;" )
295
+ assert !last_response.body.include?( "<a>hello</a>" )
296
+
297
+
298
+ # on /queues page
299
+ params = add_xss_retry # sorry, don't know how to easily make this show up on queues page otherwise.
300
+ post "/retries/#{job_params(*params)}", 'retry' => 'Retry'
301
+ assert_equal 302, last_response.status
302
+
303
+ get '/queues/foo'
304
+ assert_equal 200, last_response.status
305
+ assert last_response.body.include?( "&lt;a&gt;hello&lt;&#x2F;a&gt;" )
306
+ assert !last_response.body.include?( "<a>hello</a>" )
307
+ end
308
+
268
309
  it 'can show user defined tab' do
269
310
  begin
270
311
  Sidekiq::Web.tabs['Custom Tab'] = '/custom'
@@ -380,6 +421,22 @@ class TestWeb < Sidekiq::Test
380
421
  [msg, score]
381
422
  end
382
423
 
424
+ def add_xss_retry
425
+ msg = { 'class' => 'FailWorker',
426
+ 'args' => ['<a>hello</a>'],
427
+ 'queue' => 'foo',
428
+ 'error_message' => 'fail message: <a>hello</a>',
429
+ 'error_class' => 'RuntimeError',
430
+ 'retry_count' => 0,
431
+ 'failed_at' => Time.now.utc,
432
+ 'jid' => 'f39af2a05e8f4b24dbc0f1e4'}
433
+ score = Time.now.to_f
434
+ Sidekiq.redis do |conn|
435
+ conn.zadd('retry', score, Sidekiq.dump_json(msg))
436
+ end
437
+ [msg, score]
438
+ end
439
+
383
440
  def add_worker
384
441
  process_id = rand(1000)
385
442
  msg = "{\"queue\":\"default\",\"payload\":{\"retry\":true,\"queue\":\"default\",\"timeout\":20,\"backtrace\":5,\"class\":\"HardWorker\",\"args\":[\"bob\",10,5],\"jid\":\"2b5ad2b016f5e063a1c62872\"},\"run_at\":1361208995}"
@@ -16,11 +16,11 @@
16
16
  <td><%= msg['payload']['class'] %></td>
17
17
  <td>
18
18
  <% if msg['payload']['args'].to_s.size > 100 %>
19
- <%= msg['payload']['args'].inspect[0..100] + "... " %>
19
+ <%= h(msg['payload']['args'].inspect[0..100]) + "... " %>
20
20
  <button data-toggle="collapse" data-target="#worker_<%= index %>" class="btn btn-default btn-xs"><%= t('ShowAll') %></button>
21
- <div class="toggle" id="worker_<%= index %>" style="display: none;max-width: 750px;"><%= msg['payload']['args'] %></div>
21
+ <div class="toggle" id="worker_<%= index %>" style="display: none;max-width: 750px;"><%= h(msg['payload']['args']) %></div>
22
22
  <% else %>
23
- <%= msg['payload']['args'] %>
23
+ <%= h(msg['payload']['args']) %>
24
24
  <% end %>
25
25
  </td>
26
26
  <td><%= relative_time(msg['run_at'].is_a?(Numeric) ? Time.at(msg['run_at']) : Time.parse(msg['run_at'])) %></td>
@@ -19,11 +19,11 @@
19
19
  <td><%= msg['class'] %></td>
20
20
  <td>
21
21
  <% if msg['args'] and msg['args'].to_s.size > 100 %>
22
- <%= msg['args'].inspect[0..100] + "... " %>
22
+ <%= h(msg['args'].inspect[0..100]) + "... " %>
23
23
  <button data-toggle="collapse" data-target="#worker_<%= index %>" class="btn btn-default btn-xs"><%= t('ShowAll') %></button>
24
- <div class="toggle" id="worker_<%= index %>" style="display: none;"><%= msg['args'] %></div>
24
+ <div class="toggle" id="worker_<%= index %>" style="display: none;"><%= h(msg['args']) %></div>
25
25
  <% else %>
26
- <%= msg['args'] %>
26
+ <%= h(msg['args']) %>
27
27
  <% end %>
28
28
  </td>
29
29
  <td>
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sidekiq
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.16.0
4
+ version: 2.16.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Perham
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-10-27 00:00:00.000000000 Z
11
+ date: 2013-10-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: redis