rack 1.3.2 → 1.3.3
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.
- data/README.rdoc +6 -0
- data/Rakefile +3 -3
- data/lib/rack/conditionalget.rb +1 -0
- data/lib/rack/request.rb +16 -16
- data/lib/rack/sendfile.rb +1 -1
- data/lib/rack/showexceptions.rb +2 -2
- data/lib/rack/utils.rb +7 -1
- data/rack.gemspec +1 -1
- data/test/spec_conditionalget.rb +12 -0
- data/test/spec_mock.rb +2 -1
- data/test/spec_request.rb +13 -0
- data/test/spec_utils.rb +44 -19
- metadata +5 -5
data/README.rdoc
CHANGED
@@ -355,6 +355,12 @@ run on port 11211) and memcache-client installed.
|
|
355
355
|
* July 16, 2011: Sixteenth public release 1.3.2
|
356
356
|
* Fix for Rails and rack-test, Rack::Utils#escape calls to_s
|
357
357
|
|
358
|
+
* September 16, 2011: Seventeenth public release 1.3.3
|
359
|
+
* Fix bug with broken query parameters in Rack::ShowExceptions
|
360
|
+
* Rack::Request#cookies no longer swallows exceptions on broken input
|
361
|
+
* Prevents XSS attacks enabled by bug in Ruby 1.8's regexp engine
|
362
|
+
* Rack::ConditionalGet handles broken If-Modified-Since helpers
|
363
|
+
|
358
364
|
== Contact
|
359
365
|
|
360
366
|
Please post bugs, suggestions and patches to
|
data/Rakefile
CHANGED
@@ -64,13 +64,13 @@ file "SPEC" => 'lib/rack/lint.rb' do
|
|
64
64
|
}
|
65
65
|
end
|
66
66
|
|
67
|
-
desc "Run all the fast tests"
|
67
|
+
desc "Run all the fast + platform agnostic tests"
|
68
68
|
task :test => 'SPEC' do
|
69
69
|
opts = ENV['TEST'] || '-a'
|
70
70
|
specopts = ENV['TESTOPTS'] ||
|
71
|
-
"-q -t '^(?!Rack::Adapter|Rack::Session::Memcache|Rack::Server)'"
|
71
|
+
"-q -t '^(?!Rack::Adapter|Rack::Session::Memcache|Rack::Server|Rack::Handler)'"
|
72
72
|
|
73
|
-
sh "bacon -I./lib:./test
|
73
|
+
sh "bacon -I./lib:./test #{opts} #{specopts}"
|
74
74
|
end
|
75
75
|
|
76
76
|
desc "Run all the tests"
|
data/lib/rack/conditionalget.rb
CHANGED
data/lib/rack/request.rb
CHANGED
@@ -230,22 +230,22 @@ module Rack
|
|
230
230
|
end
|
231
231
|
|
232
232
|
def cookies
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
233
|
+
hash = @env["rack.request.cookie_hash"] ||= {}
|
234
|
+
string = @env["HTTP_COOKIE"]
|
235
|
+
|
236
|
+
hash.clear unless string
|
237
|
+
return hash if string == @env["rack.request.cookie_string"]
|
238
|
+
|
239
|
+
# According to RFC 2109:
|
240
|
+
# If multiple cookies satisfy the criteria above, they are ordered in
|
241
|
+
# the Cookie header such that those with more specific Path attributes
|
242
|
+
# precede those with less specific. Ordering with respect to other
|
243
|
+
# attributes (e.g., Domain) is unspecified.
|
244
|
+
Utils.parse_query(string, ';,').each { |k,v| hash[k] = Array === v ? v.first : v }
|
245
|
+
@env["rack.request.cookie_string"] = string
|
246
|
+
hash
|
247
|
+
rescue => error
|
248
|
+
raise error.class, "cannot parse Cookie header: #{error.message}"
|
249
249
|
end
|
250
250
|
|
251
251
|
def xhr?
|
data/lib/rack/sendfile.rb
CHANGED
@@ -80,7 +80,7 @@ module Rack
|
|
80
80
|
#
|
81
81
|
# X-Sendfile is supported under Apache 2.x using a separate module:
|
82
82
|
#
|
83
|
-
#
|
83
|
+
# https://tn123.org/mod_xsendfile/
|
84
84
|
#
|
85
85
|
# Once the module is compiled and installed, you can enable it using
|
86
86
|
# XSendFile config directive:
|
data/lib/rack/showexceptions.rb
CHANGED
@@ -277,7 +277,7 @@ TEMPLATE = <<'HTML'
|
|
277
277
|
<h2>Request information</h2>
|
278
278
|
|
279
279
|
<h3 id="get-info">GET</h3>
|
280
|
-
<%
|
280
|
+
<% if req.GET and not req.GET.empty? %>
|
281
281
|
<table class="req">
|
282
282
|
<thead>
|
283
283
|
<tr>
|
@@ -299,7 +299,7 @@ TEMPLATE = <<'HTML'
|
|
299
299
|
<% end %>
|
300
300
|
|
301
301
|
<h3 id="post-info">POST</h3>
|
302
|
-
<%
|
302
|
+
<% if req.POST and not req.POST.empty? %>
|
303
303
|
<table class="req">
|
304
304
|
<thead>
|
305
305
|
<tr>
|
data/lib/rack/utils.rb
CHANGED
@@ -146,7 +146,13 @@ module Rack
|
|
146
146
|
'"' => """,
|
147
147
|
"/" => "/"
|
148
148
|
}
|
149
|
-
|
149
|
+
if //.respond_to?(:encoding)
|
150
|
+
ESCAPE_HTML_PATTERN = Regexp.union(*ESCAPE_HTML.keys)
|
151
|
+
else
|
152
|
+
# On 1.8, there is a kcode = 'u' bug that allows for XSS otherwhise
|
153
|
+
# TODO doesn't apply to jruby, so a better condition above might be preferable?
|
154
|
+
ESCAPE_HTML_PATTERN = /#{Regexp.union(*ESCAPE_HTML.keys)}/n
|
155
|
+
end
|
150
156
|
|
151
157
|
# Escape ampersands, brackets and quotes to their HTML/XML entities.
|
152
158
|
def escape_html(string)
|
data/rack.gemspec
CHANGED
data/test/spec_conditionalget.rb
CHANGED
@@ -83,4 +83,16 @@ describe Rack::ConditionalGet do
|
|
83
83
|
response.body.should.equal 'TEST'
|
84
84
|
end
|
85
85
|
|
86
|
+
should "not affect requests with malformed HTTP_IF_NONE_MATCH" do
|
87
|
+
bad_timestamp = Time.now.strftime('%Y-%m-%d %H:%M:%S %z')
|
88
|
+
app = Rack::ConditionalGet.new(lambda { |env|
|
89
|
+
[200,{'Last-Modified'=>(Time.now - 3600).httpdate}, ['TEST']] })
|
90
|
+
|
91
|
+
response = Rack::MockRequest.new(app).
|
92
|
+
get("/", 'HTTP_IF_MODIFIED_SINCE' => bad_timestamp)
|
93
|
+
|
94
|
+
response.status.should.equal 200
|
95
|
+
response.body.should.equal 'TEST'
|
96
|
+
end
|
97
|
+
|
86
98
|
end
|
data/test/spec_mock.rb
CHANGED
@@ -175,7 +175,8 @@ describe Rack::MockRequest do
|
|
175
175
|
env["QUERY_STRING"].should.equal ""
|
176
176
|
env["PATH_INFO"].should.equal "/foo"
|
177
177
|
env["CONTENT_TYPE"].should.equal "multipart/form-data; boundary=AaB03x"
|
178
|
-
|
178
|
+
# The gsub accounts for differences in YAMLs affect on the data.
|
179
|
+
env["mock.postdata"].gsub("\r", "").length.should.equal 206
|
179
180
|
end
|
180
181
|
|
181
182
|
should "behave valid according to the Rack spec" do
|
data/test/spec_request.rb
CHANGED
@@ -351,6 +351,19 @@ describe Rack::Request do
|
|
351
351
|
req.cookies.should.equal({})
|
352
352
|
end
|
353
353
|
|
354
|
+
should "always return the same hash object" do
|
355
|
+
req = Rack::Request.new \
|
356
|
+
Rack::MockRequest.env_for("", "HTTP_COOKIE" => "foo=bar;quux=h&m")
|
357
|
+
hash = req.cookies
|
358
|
+
req.env.delete("HTTP_COOKIE")
|
359
|
+
req.cookies.should.equal(hash)
|
360
|
+
end
|
361
|
+
|
362
|
+
should "raise any errors on every request" do
|
363
|
+
req = Rack::Request.new Rack::MockRequest.env_for("", "HTTP_COOKIE" => "foo=%")
|
364
|
+
2.times { proc { req.cookies }.should.raise(ArgumentError) }
|
365
|
+
end
|
366
|
+
|
354
367
|
should "parse cookies according to RFC 2109" do
|
355
368
|
req = Rack::Request.new \
|
356
369
|
Rack::MockRequest.env_for('', 'HTTP_COOKIE' => 'foo=bar;foo=car')
|
data/test/spec_utils.rb
CHANGED
@@ -3,6 +3,14 @@ require 'rack/utils'
|
|
3
3
|
require 'rack/mock'
|
4
4
|
|
5
5
|
describe Rack::Utils do
|
6
|
+
def kcodeu
|
7
|
+
one8 = RUBY_VERSION.to_f < 1.9
|
8
|
+
default_kcode, $KCODE = $KCODE, 'U' if one8
|
9
|
+
yield
|
10
|
+
ensure
|
11
|
+
$KCODE = default_kcode if one8
|
12
|
+
end
|
13
|
+
|
6
14
|
should "escape correctly" do
|
7
15
|
Rack::Utils.escape("fo<o>bar").should.equal "fo%3Co%3Ebar"
|
8
16
|
Rack::Utils.escape("a space").should.equal "a+space"
|
@@ -21,32 +29,28 @@ describe Rack::Utils do
|
|
21
29
|
|
22
30
|
if RUBY_VERSION[/^\d+\.\d+/] == '1.8'
|
23
31
|
should "escape correctly for multibyte characters if $KCODE is set to 'U'" do
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
$KCODE = default_kcode
|
32
|
+
kcodeu do
|
33
|
+
matz_name = "\xE3\x81\xBE\xE3\x81\xA4\xE3\x82\x82\xE3\x81\xA8".unpack("a*")[0] # Matsumoto
|
34
|
+
matz_name.force_encoding("UTF-8") if matz_name.respond_to? :force_encoding
|
35
|
+
Rack::Utils.escape(matz_name).should.equal '%E3%81%BE%E3%81%A4%E3%82%82%E3%81%A8'
|
36
|
+
matz_name_sep = "\xE3\x81\xBE\xE3\x81\xA4 \xE3\x82\x82\xE3\x81\xA8".unpack("a*")[0] # Matsu moto
|
37
|
+
matz_name_sep.force_encoding("UTF-8") if matz_name_sep.respond_to? :force_encoding
|
38
|
+
Rack::Utils.escape(matz_name_sep).should.equal '%E3%81%BE%E3%81%A4+%E3%82%82%E3%81%A8'
|
39
|
+
end
|
34
40
|
end
|
35
41
|
|
36
42
|
should "unescape multibyte characters correctly if $KCODE is set to 'U'" do
|
37
|
-
|
38
|
-
|
43
|
+
kcodeu do
|
44
|
+
Rack::Utils.unescape('%E3%81%BE%E3%81%A4+%E3%82%82%E3%81%A8').should.equal(
|
39
45
|
"\xE3\x81\xBE\xE3\x81\xA4 \xE3\x82\x82\xE3\x81\xA8".unpack("a*")[0])
|
40
|
-
|
46
|
+
end
|
41
47
|
end
|
42
48
|
end
|
43
49
|
|
44
50
|
should "escape objects that responds to to_s" do
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
$KCODE = default_kcode
|
51
|
+
kcodeu do
|
52
|
+
Rack::Utils.escape(:id).should.equal "id"
|
53
|
+
end
|
50
54
|
end
|
51
55
|
|
52
56
|
if "".respond_to?(:encode)
|
@@ -219,7 +223,7 @@ describe Rack::Utils do
|
|
219
223
|
message.should.equal "value must be a Hash"
|
220
224
|
end
|
221
225
|
|
222
|
-
should "
|
226
|
+
should "escape html entities [&><'\"/]" do
|
223
227
|
Rack::Utils.escape_html("foo").should.equal "foo"
|
224
228
|
Rack::Utils.escape_html("f&o").should.equal "f&o"
|
225
229
|
Rack::Utils.escape_html("f<o").should.equal "f<o"
|
@@ -230,6 +234,27 @@ describe Rack::Utils do
|
|
230
234
|
Rack::Utils.escape_html("<foo></foo>").should.equal "<foo></foo>"
|
231
235
|
end
|
232
236
|
|
237
|
+
should "escape html entities even on MRI when it's bugged" do
|
238
|
+
test_escape = lambda do
|
239
|
+
kcodeu do
|
240
|
+
Rack::Utils.escape_html("\300<").should.equal "\300<"
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
if RUBY_VERSION.to_f < 1.9
|
245
|
+
test_escape.call
|
246
|
+
else
|
247
|
+
test_escape.should.raise(ArgumentError)
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
if "".respond_to?(:encode)
|
252
|
+
should "escape html entities in unicode strings" do
|
253
|
+
# the following will cause warnings if the regex is poorly encoded:
|
254
|
+
Rack::Utils.escape_html("☃").should.equal "☃"
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
233
258
|
should "figure out which encodings are acceptable" do
|
234
259
|
helper = lambda do |a, b|
|
235
260
|
Rack::Request.new(Rack::MockRequest.env_for("", "HTTP_ACCEPT_ENCODING" => a))
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rack
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 29
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 1
|
8
8
|
- 3
|
9
|
-
-
|
10
|
-
version: 1.3.
|
9
|
+
- 3
|
10
|
+
version: 1.3.3
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Christian Neukirchen
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-
|
18
|
+
date: 2011-09-16 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
name: bacon
|
@@ -301,7 +301,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
301
301
|
requirements: []
|
302
302
|
|
303
303
|
rubyforge_project: rack
|
304
|
-
rubygems_version: 1.8.
|
304
|
+
rubygems_version: 1.8.10
|
305
305
|
signing_key:
|
306
306
|
specification_version: 3
|
307
307
|
summary: a modular Ruby webserver interface
|