rack 1.4.5 → 1.4.6

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

Potentially problematic release.


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

@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 831b88a622b664dc64b00b2a2870464ddda19600
4
+ data.tar.gz: 269e5418115994dafa0d31264de69e535f4f2614
5
+ SHA512:
6
+ metadata.gz: 943193c81ea0787cdf1b51407826fb495c6c27f015e2d714dc313d2b377495f2db069e7e3df31ce3056b3737372c073fac81644a3d6e493e84d53dc903f1bcc3
7
+ data.tar.gz: 1a94e8b2f5dead0aa38784c3c06bb0d0d14252be517a6962914d0846af2d147ef316dabca6d1d234472ad811b5e546abf0272fca4dd12868453cee778d1ddfea
@@ -20,7 +20,7 @@ module Rack
20
20
 
21
21
  # Return the Rack release as a dotted string.
22
22
  def self.release
23
- "1.4"
23
+ "1.4.6"
24
24
  end
25
25
 
26
26
  autoload :Builder, "rack/builder"
@@ -2,6 +2,8 @@ require 'rack/utils'
2
2
 
3
3
  module Rack
4
4
  module Multipart
5
+ class MultipartLimitError < Errno::EMFILE; end
6
+
5
7
  class Parser
6
8
  BUFSIZE = 16384
7
9
 
@@ -14,7 +16,13 @@ module Rack
14
16
 
15
17
  fast_forward_to_first_boundary
16
18
 
19
+ opened_files = 0
17
20
  loop do
21
+ if Utils.multipart_part_limit > 0
22
+ raise MultipartLimitError, 'Maximum file multiparts in content reached' if opened_files >= Utils.multipart_part_limit
23
+ opened_files += 1
24
+ end
25
+
18
26
  head, filename, content_type, name, body =
19
27
  get_current_head_and_filename_and_content_type_and_name_and_body
20
28
 
@@ -337,6 +337,8 @@ module Rack
337
337
  return :exited unless ::File.exist?(options[:pid])
338
338
 
339
339
  pid = ::File.read(options[:pid]).to_i
340
+ return :dead if pid == 0
341
+
340
342
  Process.kill(0, pid)
341
343
  :running
342
344
  rescue Errno::ESRCH
@@ -51,12 +51,23 @@ module Rack
51
51
 
52
52
  class << self
53
53
  attr_accessor :key_space_limit
54
+ attr_accessor :param_depth_limit
55
+ attr_accessor :multipart_part_limit
54
56
  end
55
57
 
56
58
  # The default number of bytes to allow parameter keys to take up.
57
59
  # This helps prevent a rogue client from flooding a Request.
58
60
  self.key_space_limit = 65536
59
61
 
62
+ # Default depth at which the parameter parser will raise an exception for
63
+ # being too deep. This helps prevent SystemStackErrors
64
+ self.param_depth_limit = 100
65
+ #
66
+ # The maximum number of parts a request can contain. Accepting to many part
67
+ # can lead to the server running out of file handles.
68
+ # Set to `0` for no limit.
69
+ self.multipart_part_limit = (ENV['RACK_MULTIPART_PART_LIMIT'] || 128).to_i
70
+
60
71
  # Stolen from Mongrel, with some small modifications:
61
72
  # Parses a query string by breaking it up at the '&'
62
73
  # and ';' characters. You can also use this to parse
@@ -100,7 +111,9 @@ module Rack
100
111
  end
101
112
  module_function :parse_nested_query
102
113
 
103
- def normalize_params(params, name, v = nil)
114
+ def normalize_params(params, name, v = nil, depth = Utils.param_depth_limit)
115
+ raise RangeError if depth <= 0
116
+
104
117
  name =~ %r(\A[\[\]]*([^\[\]]+)\]*)
105
118
  k = $1 || ''
106
119
  after = $' || ''
@@ -118,14 +131,14 @@ module Rack
118
131
  params[k] ||= []
119
132
  raise TypeError, "expected Array (got #{params[k].class.name}) for param `#{k}'" unless params[k].is_a?(Array)
120
133
  if params_hash_type?(params[k].last) && !params[k].last.key?(child_key)
121
- normalize_params(params[k].last, child_key, v)
134
+ normalize_params(params[k].last, child_key, v, depth - 1)
122
135
  else
123
- params[k] << normalize_params(params.class.new, child_key, v)
136
+ params[k] << normalize_params(params.class.new, child_key, v, depth - 1)
124
137
  end
125
138
  else
126
139
  params[k] ||= params.class.new
127
140
  raise TypeError, "expected Hash (got #{params[k].class.name}) for param `#{k}'" unless params_hash_type?(params[k])
128
- params[k] = normalize_params(params[k], after, v)
141
+ params[k] = normalize_params(params[k], after, v, depth - 1)
129
142
  end
130
143
 
131
144
  return params
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "rack"
3
- s.version = "1.4.5"
3
+ s.version = "1.4.6"
4
4
  s.platform = Gem::Platform::RUBY
5
5
  s.summary = "a modular Ruby webserver interface"
6
6
 
@@ -364,22 +364,29 @@ Content-Type: image/jpeg\r
364
364
  end
365
365
 
366
366
  it "builds complete params with the chunk size of 16384 slicing exactly on boundary" do
367
- data = File.open(multipart_file("fail_16384_nofile")) { |f| f.read }.gsub(/\n/, "\r\n")
368
- options = {
369
- "CONTENT_TYPE" => "multipart/form-data; boundary=----WebKitFormBoundaryWsY0GnpbI5U7ztzo",
370
- "CONTENT_LENGTH" => data.length.to_s,
371
- :input => StringIO.new(data)
372
- }
373
- env = Rack::MockRequest.env_for("/", options)
374
- params = Rack::Multipart.parse_multipart(env)
375
-
376
- params.should.not.equal nil
377
- params.keys.should.include "AAAAAAAAAAAAAAAAAAA"
378
- params["AAAAAAAAAAAAAAAAAAA"].keys.should.include "PLAPLAPLA_MEMMEMMEMM_ATTRATTRER"
379
- params["AAAAAAAAAAAAAAAAAAA"]["PLAPLAPLA_MEMMEMMEMM_ATTRATTRER"].keys.should.include "new"
380
- params["AAAAAAAAAAAAAAAAAAA"]["PLAPLAPLA_MEMMEMMEMM_ATTRATTRER"]["new"].keys.should.include "-2"
381
- params["AAAAAAAAAAAAAAAAAAA"]["PLAPLAPLA_MEMMEMMEMM_ATTRATTRER"]["new"]["-2"].keys.should.include "ba_unit_id"
382
- params["AAAAAAAAAAAAAAAAAAA"]["PLAPLAPLA_MEMMEMMEMM_ATTRATTRER"]["new"]["-2"]["ba_unit_id"].should.equal "1017"
367
+ begin
368
+ previous_limit = Rack::Utils.multipart_part_limit
369
+ Rack::Utils.multipart_part_limit = 256
370
+
371
+ data = File.open(multipart_file("fail_16384_nofile"), 'rb') { |f| f.read }.gsub(/\n/, "\r\n")
372
+ options = {
373
+ "CONTENT_TYPE" => "multipart/form-data; boundary=----WebKitFormBoundaryWsY0GnpbI5U7ztzo",
374
+ "CONTENT_LENGTH" => data.length.to_s,
375
+ :input => StringIO.new(data)
376
+ }
377
+ env = Rack::MockRequest.env_for("/", options)
378
+ params = Rack::Multipart.parse_multipart(env)
379
+
380
+ params.should.not.equal nil
381
+ params.keys.should.include "AAAAAAAAAAAAAAAAAAA"
382
+ params["AAAAAAAAAAAAAAAAAAA"].keys.should.include "PLAPLAPLA_MEMMEMMEMM_ATTRATTRER"
383
+ params["AAAAAAAAAAAAAAAAAAA"]["PLAPLAPLA_MEMMEMMEMM_ATTRATTRER"].keys.should.include "new"
384
+ params["AAAAAAAAAAAAAAAAAAA"]["PLAPLAPLA_MEMMEMMEMM_ATTRATTRER"]["new"].keys.should.include "-2"
385
+ params["AAAAAAAAAAAAAAAAAAA"]["PLAPLAPLA_MEMMEMMEMM_ATTRATTRER"]["new"]["-2"].keys.should.include "ba_unit_id"
386
+ params["AAAAAAAAAAAAAAAAAAA"]["PLAPLAPLA_MEMMEMMEMM_ATTRATTRER"]["new"]["-2"]["ba_unit_id"].should.equal "1017"
387
+ ensure
388
+ Rack::Utils.multipart_part_limit = previous_limit
389
+ end
383
390
  end
384
391
 
385
392
  should "return nil if no UploadedFiles were used" do
@@ -2,6 +2,7 @@ require 'stringio'
2
2
  require 'cgi'
3
3
  require 'rack/request'
4
4
  require 'rack/mock'
5
+ require 'securerandom'
5
6
 
6
7
  describe Rack::Request do
7
8
  should "wrap the rack variables" do
@@ -613,6 +614,22 @@ EOF
613
614
  f[:tempfile].size.should.equal 76
614
615
  end
615
616
 
617
+ should "MultipartLimitError when request has too many multipart parts if limit set" do
618
+ begin
619
+ data = 10000.times.map { "--AaB03x\r\nContent-Type: text/plain\r\nContent-Disposition: attachment; name=#{SecureRandom.hex(10)}; filename=#{SecureRandom.hex(10)}\r\n\r\ncontents\r\n" }.join("\r\n")
620
+ data += "--AaB03x--\r"
621
+
622
+ options = {
623
+ "CONTENT_TYPE" => "multipart/form-data; boundary=AaB03x",
624
+ "CONTENT_LENGTH" => data.length.to_s,
625
+ :input => StringIO.new(data)
626
+ }
627
+
628
+ request = Rack::Request.new Rack::MockRequest.env_for("/", options)
629
+ lambda { request.POST }.should.raise(Rack::Multipart::MultipartLimitError)
630
+ end
631
+ end
632
+
616
633
  should "parse big multipart form data" do
617
634
  input = <<EOF
618
635
  --AaB03x\r
@@ -123,6 +123,18 @@ describe Rack::Utils do
123
123
  Rack::Utils.parse_query(",foo=bar;,", ";,").should.equal "foo" => "bar"
124
124
  end
125
125
 
126
+ should "raise an exception if the params are too deep" do
127
+ len = Rack::Utils.param_depth_limit
128
+
129
+ lambda {
130
+ Rack::Utils.parse_nested_query("foo#{"[a]" * len}=bar")
131
+ }.should.raise(RangeError)
132
+
133
+ lambda {
134
+ Rack::Utils.parse_nested_query("foo#{"[a]" * (len - 1)}=bar")
135
+ }.should.not.raise
136
+ end
137
+
126
138
  should "parse nested query strings correctly" do
127
139
  Rack::Utils.parse_nested_query("foo").
128
140
  should.equal "foo" => nil
metadata CHANGED
@@ -1,128 +1,120 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: rack
3
- version: !ruby/object:Gem::Version
4
- hash: 13
5
- prerelease:
6
- segments:
7
- - 1
8
- - 4
9
- - 5
10
- version: 1.4.5
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.4.6
11
5
  platform: ruby
12
- authors:
6
+ authors:
13
7
  - Christian Neukirchen
14
8
  autorequire:
15
9
  bindir: bin
16
10
  cert_chain: []
17
-
18
- date: 2013-02-08 00:00:00 Z
19
- dependencies:
20
- - !ruby/object:Gem::Dependency
11
+ date: 2015-06-16 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
21
14
  name: bacon
22
- prerelease: false
23
- requirement: &id001 !ruby/object:Gem::Requirement
24
- none: false
25
- requirements:
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
26
17
  - - ">="
27
- - !ruby/object:Gem::Version
28
- hash: 3
29
- segments:
30
- - 0
31
- version: "0"
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
32
20
  type: :development
33
- version_requirements: *id001
34
- - !ruby/object:Gem::Dependency
35
- name: rake
36
21
  prerelease: false
37
- requirement: &id002 !ruby/object:Gem::Requirement
38
- none: false
39
- requirements:
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
40
24
  - - ">="
41
- - !ruby/object:Gem::Version
42
- hash: 3
43
- segments:
44
- - 0
45
- version: "0"
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
46
34
  type: :development
47
- version_requirements: *id002
48
- - !ruby/object:Gem::Dependency
49
- name: ruby-fcgi
50
35
  prerelease: false
51
- requirement: &id003 !ruby/object:Gem::Requirement
52
- none: false
53
- requirements:
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
54
38
  - - ">="
55
- - !ruby/object:Gem::Version
56
- hash: 3
57
- segments:
58
- - 0
59
- version: "0"
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: ruby-fcgi
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
60
48
  type: :development
61
- version_requirements: *id003
62
- - !ruby/object:Gem::Dependency
63
- name: memcache-client
64
49
  prerelease: false
65
- requirement: &id004 !ruby/object:Gem::Requirement
66
- none: false
67
- requirements:
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: memcache-client
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
68
59
  - - ">="
69
- - !ruby/object:Gem::Version
70
- hash: 3
71
- segments:
72
- - 0
73
- version: "0"
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
74
62
  type: :development
75
- version_requirements: *id004
76
- - !ruby/object:Gem::Dependency
77
- name: mongrel
78
63
  prerelease: false
79
- requirement: &id005 !ruby/object:Gem::Requirement
80
- none: false
81
- requirements:
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: mongrel
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
82
73
  - - ">="
83
- - !ruby/object:Gem::Version
84
- hash: 3904189667
85
- segments:
86
- - 1
87
- - 2
88
- - 0
89
- - pre
90
- - 2
74
+ - !ruby/object:Gem::Version
91
75
  version: 1.2.0.pre2
92
76
  type: :development
93
- version_requirements: *id005
94
- - !ruby/object:Gem::Dependency
95
- name: thin
96
77
  prerelease: false
97
- requirement: &id006 !ruby/object:Gem::Requirement
98
- none: false
99
- requirements:
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
100
80
  - - ">="
101
- - !ruby/object:Gem::Version
102
- hash: 3
103
- segments:
104
- - 0
105
- version: "0"
81
+ - !ruby/object:Gem::Version
82
+ version: 1.2.0.pre2
83
+ - !ruby/object:Gem::Dependency
84
+ name: thin
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
106
90
  type: :development
107
- version_requirements: *id006
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
108
97
  description: |
109
98
  Rack provides a minimal, modular and adaptable interface for developing
110
99
  web applications in Ruby. By wrapping HTTP requests and responses in
111
100
  the simplest way possible, it unifies and distills the API for web
112
101
  servers, web frameworks, and software in between (the so-called
113
102
  middleware) into a single method call.
114
-
115
- Also see http://rack.github.com/.
116
103
 
104
+ Also see http://rack.github.com/.
117
105
  email: chneukirchen@gmail.com
118
- executables:
106
+ executables:
119
107
  - rackup
120
108
  extensions: []
121
-
122
- extra_rdoc_files:
109
+ extra_rdoc_files:
123
110
  - README.rdoc
124
111
  - KNOWN-ISSUES
125
- files:
112
+ files:
113
+ - COPYING
114
+ - KNOWN-ISSUES
115
+ - README.rdoc
116
+ - Rakefile
117
+ - SPEC
126
118
  - bin/rackup
127
119
  - contrib/rack.png
128
120
  - contrib/rack.svg
@@ -131,6 +123,7 @@ files:
131
123
  - example/lobster.ru
132
124
  - example/protectedlobster.rb
133
125
  - example/protectedlobster.ru
126
+ - lib/rack.rb
134
127
  - lib/rack/auth/abstract/handler.rb
135
128
  - lib/rack/auth/abstract/request.rb
136
129
  - lib/rack/auth/basic.rb
@@ -154,6 +147,7 @@ files:
154
147
  - lib/rack/directory.rb
155
148
  - lib/rack/etag.rb
156
149
  - lib/rack/file.rb
150
+ - lib/rack/handler.rb
157
151
  - lib/rack/handler/cgi.rb
158
152
  - lib/rack/handler/evented_mongrel.rb
159
153
  - lib/rack/handler/fastcgi.rb
@@ -163,7 +157,6 @@ files:
163
157
  - lib/rack/handler/swiftiplied_mongrel.rb
164
158
  - lib/rack/handler/thin.rb
165
159
  - lib/rack/handler/webrick.rb
166
- - lib/rack/handler.rb
167
160
  - lib/rack/head.rb
168
161
  - lib/rack/lint.rb
169
162
  - lib/rack/lobster.rb
@@ -172,10 +165,10 @@ files:
172
165
  - lib/rack/methodoverride.rb
173
166
  - lib/rack/mime.rb
174
167
  - lib/rack/mock.rb
168
+ - lib/rack/multipart.rb
175
169
  - lib/rack/multipart/generator.rb
176
170
  - lib/rack/multipart/parser.rb
177
171
  - lib/rack/multipart/uploaded_file.rb
178
- - lib/rack/multipart.rb
179
172
  - lib/rack/nulllogger.rb
180
173
  - lib/rack/recursive.rb
181
174
  - lib/rack/reloader.rb
@@ -194,7 +187,7 @@ files:
194
187
  - lib/rack/static.rb
195
188
  - lib/rack/urlmap.rb
196
189
  - lib/rack/utils.rb
197
- - lib/rack.rb
190
+ - rack.gemspec
198
191
  - test/builder/anything.rb
199
192
  - test/builder/comment.ru
200
193
  - test/builder/end.ru
@@ -289,46 +282,30 @@ files:
289
282
  - test/testrequest.rb
290
283
  - test/unregistered_handler/rack/handler/unregistered.rb
291
284
  - test/unregistered_handler/rack/handler/unregistered_long_one.rb
292
- - COPYING
293
- - KNOWN-ISSUES
294
- - rack.gemspec
295
- - Rakefile
296
- - README.rdoc
297
- - SPEC
298
285
  homepage: http://rack.github.com/
299
286
  licenses: []
300
-
287
+ metadata: {}
301
288
  post_install_message:
302
289
  rdoc_options: []
303
-
304
- require_paths:
290
+ require_paths:
305
291
  - lib
306
- required_ruby_version: !ruby/object:Gem::Requirement
307
- none: false
308
- requirements:
292
+ required_ruby_version: !ruby/object:Gem::Requirement
293
+ requirements:
309
294
  - - ">="
310
- - !ruby/object:Gem::Version
311
- hash: 3
312
- segments:
313
- - 0
314
- version: "0"
315
- required_rubygems_version: !ruby/object:Gem::Requirement
316
- none: false
317
- requirements:
295
+ - !ruby/object:Gem::Version
296
+ version: '0'
297
+ required_rubygems_version: !ruby/object:Gem::Requirement
298
+ requirements:
318
299
  - - ">="
319
- - !ruby/object:Gem::Version
320
- hash: 3
321
- segments:
322
- - 0
323
- version: "0"
300
+ - !ruby/object:Gem::Version
301
+ version: '0'
324
302
  requirements: []
325
-
326
303
  rubyforge_project: rack
327
- rubygems_version: 1.8.24
304
+ rubygems_version: 2.4.5
328
305
  signing_key:
329
- specification_version: 3
306
+ specification_version: 4
330
307
  summary: a modular Ruby webserver interface
331
- test_files:
308
+ test_files:
332
309
  - test/spec_auth.rb
333
310
  - test/spec_auth_basic.rb
334
311
  - test/spec_auth_digest.rb
@@ -376,4 +353,3 @@ test_files:
376
353
  - test/spec_urlmap.rb
377
354
  - test/spec_utils.rb
378
355
  - test/spec_webrick.rb
379
- has_rdoc: