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.
- checksums.yaml +7 -0
- data/lib/rack.rb +1 -1
- data/lib/rack/multipart/parser.rb +8 -0
- data/lib/rack/server.rb +2 -0
- data/lib/rack/utils.rb +17 -4
- data/rack.gemspec +1 -1
- data/test/spec_multipart.rb +23 -16
- data/test/spec_request.rb +17 -0
- data/test/spec_utils.rb +12 -0
- metadata +97 -121
checksums.yaml
ADDED
@@ -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
|
data/lib/rack.rb
CHANGED
@@ -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
|
|
data/lib/rack/server.rb
CHANGED
data/lib/rack/utils.rb
CHANGED
@@ -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
|
data/rack.gemspec
CHANGED
data/test/spec_multipart.rb
CHANGED
@@ -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
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
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
|
data/test/spec_request.rb
CHANGED
@@ -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
|
data/test/spec_utils.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
19
|
-
|
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
|
-
|
23
|
-
|
24
|
-
none: false
|
25
|
-
requirements:
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
26
17
|
- - ">="
|
27
|
-
- !ruby/object:Gem::Version
|
28
|
-
|
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
|
-
|
38
|
-
|
39
|
-
requirements:
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
40
24
|
- - ">="
|
41
|
-
- !ruby/object:Gem::Version
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
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
|
-
|
52
|
-
|
53
|
-
requirements:
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
54
38
|
- - ">="
|
55
|
-
- !ruby/object:Gem::Version
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
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
|
-
|
66
|
-
|
67
|
-
|
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
|
-
|
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
|
-
|
80
|
-
|
81
|
-
|
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
|
-
|
98
|
-
|
99
|
-
requirements:
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
100
80
|
- - ">="
|
101
|
-
- !ruby/object:Gem::Version
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
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
|
-
|
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
|
-
-
|
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
|
-
|
308
|
-
requirements:
|
292
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
293
|
+
requirements:
|
309
294
|
- - ">="
|
310
|
-
- !ruby/object:Gem::Version
|
311
|
-
|
312
|
-
|
313
|
-
|
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
|
-
|
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:
|
304
|
+
rubygems_version: 2.4.5
|
328
305
|
signing_key:
|
329
|
-
specification_version:
|
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:
|