diff -Nru ruby-rack-1.3.1/debian/changelog ruby-rack-1.3.5/debian/changelog --- ruby-rack-1.3.1/debian/changelog 2011-07-28 06:31:31.000000000 +0000 +++ ruby-rack-1.3.5/debian/changelog 2011-12-21 09:58:14.000000000 +0000 @@ -1,3 +1,13 @@ +ruby-rack (1.3.5-1) unstable; urgency=low + + * New upstream release. + * Fix my email address. + * Fix priority of transitional packages. + * TESTS ARE DISABLED: many dependencies required for tests are not + packaged yet. + + -- Lucas Nussbaum Wed, 21 Dec 2011 10:52:37 +0100 + ruby-rack (1.3.1-1) unstable; urgency=low * New upstream release: 1.3.1 diff -Nru ruby-rack-1.3.1/debian/control ruby-rack-1.3.5/debian/control --- ruby-rack-1.3.1/debian/control 2011-07-28 06:31:31.000000000 +0000 +++ ruby-rack-1.3.5/debian/control 2011-12-21 09:53:02.000000000 +0000 @@ -2,7 +2,7 @@ Section: ruby Priority: optional Maintainer: Debian Ruby Extras Maintainers -Uploaders: Lucas Nussbaum , Youhei SASAKI +Uploaders: Lucas Nussbaum , Youhei SASAKI DM-Upload-Allowed: yes Build-Depends: debhelper (>= 7.0.50~), gem2deb (>= 0.2.1) #Build-Depends: debhelper (>= 7.0.50~), gem2deb (>= 0.2.1), ruby-bacon @@ -31,6 +31,7 @@ which all Rack applications should conform to. Package: librack-ruby1.9.1 +Priority: extra Section: oldlibs Architecture: all Depends: ${misc:Depends}, ruby-rack @@ -39,6 +40,7 @@ package. It can safely be removed. Package: librack-ruby1.8 +Priority: extra Section: oldlibs Architecture: all Depends: ${misc:Depends}, ruby-rack @@ -47,6 +49,7 @@ package. It can safely be removed. Package: librack-ruby +Priority: extra Section: oldlibs Architecture: all Depends: ${misc:Depends}, ruby-rack diff -Nru ruby-rack-1.3.1/lib/rack/backports/uri/common_18.rb ruby-rack-1.3.5/lib/rack/backports/uri/common_18.rb --- ruby-rack-1.3.1/lib/rack/backports/uri/common_18.rb 1970-01-01 00:00:00.000000000 +0000 +++ ruby-rack-1.3.5/lib/rack/backports/uri/common_18.rb 2011-10-22 04:16:19.000000000 +0000 @@ -0,0 +1,70 @@ +# :stopdoc: + +# Stolen from ruby core's uri/common.rb, with modifications to support 1.8.x +# +# https://github.com/ruby/ruby/blob/trunk/lib/uri/common.rb +# +# + +module URI + TBLENCWWWCOMP_ = {} # :nodoc: + TBLDECWWWCOMP_ = {} # :nodoc: + + # Encode given +s+ to URL-encoded form data. + # + # This method doesn't convert *, -, ., 0-9, A-Z, _, a-z, but does convert SP + # (ASCII space) to + and converts others to %XX. + # + # This is an implementation of + # http://www.w3.org/TR/html5/forms.html#url-encoded-form-data + # + # See URI.decode_www_form_component, URI.encode_www_form + def self.encode_www_form_component(s) + str = s.to_s + if RUBY_VERSION < "1.9" && $KCODE =~ /u/i + str.gsub(/([^ a-zA-Z0-9_.-]+)/) do + '%' + $1.unpack('H2' * Rack::Utils.bytesize($1)).join('%').upcase + end.tr(' ', '+') + else + if TBLENCWWWCOMP_.empty? + tbl = {} + 256.times do |i| + tbl[i.chr] = '%%%02X' % i + end + tbl[' '] = '+' + begin + TBLENCWWWCOMP_.replace(tbl) + TBLENCWWWCOMP_.freeze + rescue + end + end + str.gsub(/[^*\-.0-9A-Z_a-z]/) {|m| TBLENCWWWCOMP_[m]} + end + end + + # Decode given +str+ of URL-encoded form data. + # + # This decods + to SP. + # + # See URI.encode_www_form_component, URI.decode_www_form + def self.decode_www_form_component(str, enc=nil) + if TBLDECWWWCOMP_.empty? + tbl = {} + 256.times do |i| + h, l = i>>4, i&15 + tbl['%%%X%X' % [h, l]] = i.chr + tbl['%%%x%X' % [h, l]] = i.chr + tbl['%%%X%x' % [h, l]] = i.chr + tbl['%%%x%x' % [h, l]] = i.chr + end + tbl['+'] = ' ' + begin + TBLDECWWWCOMP_.replace(tbl) + TBLDECWWWCOMP_.freeze + rescue + end + end + raise ArgumentError, "invalid %-encoding (#{str})" unless /\A(?:%[0-9a-fA-F]{2}|[^%])*\z/ =~ str + str.gsub(/\+|%[0-9a-fA-F]{2}/) {|m| TBLDECWWWCOMP_[m]} + end +end diff -Nru ruby-rack-1.3.1/lib/rack/backports/uri/common_192.rb ruby-rack-1.3.5/lib/rack/backports/uri/common_192.rb --- ruby-rack-1.3.1/lib/rack/backports/uri/common_192.rb 1970-01-01 00:00:00.000000000 +0000 +++ ruby-rack-1.3.5/lib/rack/backports/uri/common_192.rb 2011-10-22 04:16:19.000000000 +0000 @@ -0,0 +1,55 @@ +# :stopdoc: + +# Stolen from ruby core's uri/common.rb @32618ba to fix DoS issues in 1.9.2 +# +# https://github.com/ruby/ruby/blob/32618ba7438a2247042bba9b5d85b5d49070f5e5/lib/uri/common.rb +# +# Issue: +# http://redmine.ruby-lang.org/issues/5149 +# +# Relevant Fixes: +# https://github.com/ruby/ruby/commit/b5f91deee04aa6ccbe07c23c8222b937c22a799b +# https://github.com/ruby/ruby/commit/93177c1e5c3906abf14472ae0b905d8b5c72ce1b +# +# This should probably be removed once there is a Ruby 1.9.2 patch level that +# includes this fix. + +require 'uri/common' + +module URI + def self.decode_www_form(str, enc=Encoding::UTF_8) + return [] if str.empty? + unless /\A#{WFKV_}=#{WFKV_}(?:[;&]#{WFKV_}=#{WFKV_})*\z/o =~ str + raise ArgumentError, "invalid data of application/x-www-form-urlencoded (#{str})" + end + ary = [] + $&.scan(/([^=;&]+)=([^;&]*)/) do + ary << [decode_www_form_component($1, enc), decode_www_form_component($2, enc)] + end + ary + end + + def self.decode_www_form_component(str, enc=Encoding::UTF_8) + if TBLDECWWWCOMP_.empty? + tbl = {} + 256.times do |i| + h, l = i>>4, i&15 + tbl['%%%X%X' % [h, l]] = i.chr + tbl['%%%x%X' % [h, l]] = i.chr + tbl['%%%X%x' % [h, l]] = i.chr + tbl['%%%x%x' % [h, l]] = i.chr + end + tbl['+'] = ' ' + begin + TBLDECWWWCOMP_.replace(tbl) + TBLDECWWWCOMP_.freeze + rescue + end + end + raise ArgumentError, "invalid %-encoding (#{str})" unless /\A[^%]*(?:%\h\h[^%]*)*\z/ =~ str + str.gsub(/\+|%\h\h/, TBLDECWWWCOMP_).force_encoding(enc) + end + + remove_const :WFKV_ + WFKV_ = '(?:[^%#=;&]*(?:%\h\h[^%#=;&]*)*)' # :nodoc: +end diff -Nru ruby-rack-1.3.1/lib/rack/backports/uri/common.rb ruby-rack-1.3.5/lib/rack/backports/uri/common.rb --- ruby-rack-1.3.1/lib/rack/backports/uri/common.rb 2011-07-25 15:56:14.000000000 +0000 +++ ruby-rack-1.3.5/lib/rack/backports/uri/common.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,70 +0,0 @@ -# :stopdoc: - -# Stolen from ruby core's uri/common.rb, with modifications to support 1.8.x -# -# https://github.com/ruby/ruby/blob/trunk/lib/uri/common.rb -# -# - -module URI - TBLENCWWWCOMP_ = {} # :nodoc: - TBLDECWWWCOMP_ = {} # :nodoc: - - # Encode given +str+ to URL-encoded form data. - # - # This method doesn't convert *, -, ., 0-9, A-Z, _, a-z, but does convert SP - # (ASCII space) to + and converts others to %XX. - # - # This is an implementation of - # http://www.w3.org/TR/html5/forms.html#url-encoded-form-data - # - # See URI.decode_www_form_component, URI.encode_www_form - def self.encode_www_form_component(str) - if RUBY_VERSION < "1.9" && $KCODE =~ /u/i - str.gsub(/([^ a-zA-Z0-9_.-]+)/) do - '%' + $1.unpack('H2' * Rack::Utils.bytesize($1)).join('%').upcase - end.tr(' ', '+') - else - if TBLENCWWWCOMP_.empty? - tbl = {} - 256.times do |i| - tbl[i.chr] = '%%%02X' % i - end - tbl[' '] = '+' - begin - TBLENCWWWCOMP_.replace(tbl) - TBLENCWWWCOMP_.freeze - rescue - end - end - str = str.to_s - str.gsub(/[^*\-.0-9A-Z_a-z]/) {|m| TBLENCWWWCOMP_[m]} - end - end - - # Decode given +str+ of URL-encoded form data. - # - # This decods + to SP. - # - # See URI.encode_www_form_component, URI.decode_www_form - def self.decode_www_form_component(str, enc=nil) - if TBLDECWWWCOMP_.empty? - tbl = {} - 256.times do |i| - h, l = i>>4, i&15 - tbl['%%%X%X' % [h, l]] = i.chr - tbl['%%%x%X' % [h, l]] = i.chr - tbl['%%%X%x' % [h, l]] = i.chr - tbl['%%%x%x' % [h, l]] = i.chr - end - tbl['+'] = ' ' - begin - TBLDECWWWCOMP_.replace(tbl) - TBLDECWWWCOMP_.freeze - rescue - end - end - raise ArgumentError, "invalid %-encoding (#{str})" unless /\A(?:%[0-9a-fA-F]{2}|[^%])*\z/ =~ str - str.gsub(/\+|%[0-9a-fA-F]{2}/) {|m| TBLDECWWWCOMP_[m]} - end -end diff -Nru ruby-rack-1.3.1/lib/rack/body_proxy.rb ruby-rack-1.3.5/lib/rack/body_proxy.rb --- ruby-rack-1.3.1/lib/rack/body_proxy.rb 2011-07-25 15:56:14.000000000 +0000 +++ ruby-rack-1.3.5/lib/rack/body_proxy.rb 2011-10-22 04:16:19.000000000 +0000 @@ -9,13 +9,10 @@ end def close - raise IOError, "closed stream" if @closed - begin - @body.close if @body.respond_to? :close - ensure - @block.call - @closed = true - end + return if @closed + @closed = true + @body.close if @body.respond_to? :close + @block.call end def closed? diff -Nru ruby-rack-1.3.1/lib/rack/conditionalget.rb ruby-rack-1.3.5/lib/rack/conditionalget.rb --- ruby-rack-1.3.1/lib/rack/conditionalget.rb 2011-07-25 15:56:14.000000000 +0000 +++ ruby-rack-1.3.5/lib/rack/conditionalget.rb 2011-10-22 04:16:19.000000000 +0000 @@ -56,6 +56,7 @@ def modified_since?(modified_since, headers) last_modified = to_rfc2822(headers['Last-Modified']) and + modified_since and modified_since >= last_modified end diff -Nru ruby-rack-1.3.1/lib/rack/mime.rb ruby-rack-1.3.5/lib/rack/mime.rb --- ruby-rack-1.3.1/lib/rack/mime.rb 2011-07-25 15:56:14.000000000 +0000 +++ ruby-rack-1.3.5/lib/rack/mime.rb 2011-10-22 04:16:19.000000000 +0000 @@ -28,6 +28,9 @@ # list = WEBrick::HTTPUtils.load_mime_types('/etc/mime.types') # Rack::Mime::MIME_TYPES.merge!(list) # + # N.B. On Ubuntu the mime.types file does not include the leading period, so + # users may need to modify the data before merging into the hash. + # # To add the list mongrel provides, use: # # require 'mongrel/handlers' diff -Nru ruby-rack-1.3.1/lib/rack/request.rb ruby-rack-1.3.5/lib/rack/request.rb --- ruby-rack-1.3.1/lib/rack/request.rb 2011-07-25 15:56:14.000000000 +0000 +++ ruby-rack-1.3.5/lib/rack/request.rb 2011-10-22 04:16:19.000000000 +0000 @@ -230,22 +230,22 @@ end def cookies - return {} unless @env["HTTP_COOKIE"] + hash = @env["rack.request.cookie_hash"] ||= {} + string = @env["HTTP_COOKIE"] - if @env["rack.request.cookie_string"] == @env["HTTP_COOKIE"] - @env["rack.request.cookie_hash"] - else - @env["rack.request.cookie_string"] = @env["HTTP_COOKIE"] - # According to RFC 2109: - # If multiple cookies satisfy the criteria above, they are ordered in - # the Cookie header such that those with more specific Path attributes - # precede those with less specific. Ordering with respect to other - # attributes (e.g., Domain) is unspecified. - @env["rack.request.cookie_hash"] = - Hash[*Utils.parse_query(@env["rack.request.cookie_string"], ';,').map {|k,v| - [k, Array === v ? v.first : v] - }.flatten] - end + hash.clear unless string + return hash if string == @env["rack.request.cookie_string"] + + # According to RFC 2109: + # If multiple cookies satisfy the criteria above, they are ordered in + # the Cookie header such that those with more specific Path attributes + # precede those with less specific. Ordering with respect to other + # attributes (e.g., Domain) is unspecified. + Utils.parse_query(string, ';,').each { |k,v| hash[k] = Array === v ? v.first : v } + @env["rack.request.cookie_string"] = string + hash + rescue => error + raise error.class, "cannot parse Cookie header: #{error.message}" end def xhr? diff -Nru ruby-rack-1.3.1/lib/rack/sendfile.rb ruby-rack-1.3.5/lib/rack/sendfile.rb --- ruby-rack-1.3.1/lib/rack/sendfile.rb 2011-07-25 15:56:14.000000000 +0000 +++ ruby-rack-1.3.5/lib/rack/sendfile.rb 2011-10-22 04:16:19.000000000 +0000 @@ -80,7 +80,7 @@ # # X-Sendfile is supported under Apache 2.x using a separate module: # - # http://tn123.ath.cx/mod_xsendfile/ + # https://tn123.org/mod_xsendfile/ # # Once the module is compiled and installed, you can enable it using # XSendFile config directive: diff -Nru ruby-rack-1.3.1/lib/rack/showexceptions.rb ruby-rack-1.3.5/lib/rack/showexceptions.rb --- ruby-rack-1.3.1/lib/rack/showexceptions.rb 2011-07-25 15:56:14.000000000 +0000 +++ ruby-rack-1.3.5/lib/rack/showexceptions.rb 2011-10-22 04:16:19.000000000 +0000 @@ -277,7 +277,7 @@

Request information

GET

- <% unless req.GET.empty? %> + <% if req.GET and not req.GET.empty? %> @@ -299,7 +299,7 @@ <% end %>

POST

- <% unless req.POST.empty? %> + <% if req.POST and not req.POST.empty? %>
diff -Nru ruby-rack-1.3.1/lib/rack/utils.rb ruby-rack-1.3.5/lib/rack/utils.rb --- ruby-rack-1.3.1/lib/rack/utils.rb 2011-07-25 15:56:14.000000000 +0000 +++ ruby-rack-1.3.5/lib/rack/utils.rb 2011-10-22 04:16:19.000000000 +0000 @@ -6,9 +6,10 @@ major, minor, patch = RUBY_VERSION.split('.').map { |v| v.to_i } -if (major == 1 && minor < 9) || (major == 1 && minor == 9 && patch < 2) - # pull in backports - require 'rack/backports/uri/common' +if major == 1 && minor < 9 + require 'rack/backports/uri/common_18' +elsif major == 1 && minor == 9 && patch < 3 + require 'rack/backports/uri/common_192' else require 'uri/common' end @@ -18,7 +19,7 @@ # applications adopted from all kinds of Ruby libraries. module Utils - # URI escapes a string. (CGI style space to +) + # URI escapes. (CGI style space to +) def escape(s) URI.encode_www_form_component(s) end @@ -146,7 +147,13 @@ '"' => """, "/" => "/" } - ESCAPE_HTML_PATTERN = Regexp.union(*ESCAPE_HTML.keys) + if //.respond_to?(:encoding) + ESCAPE_HTML_PATTERN = Regexp.union(*ESCAPE_HTML.keys) + else + # On 1.8, there is a kcode = 'u' bug that allows for XSS otherwhise + # TODO doesn't apply to jruby, so a better condition above might be preferable? + ESCAPE_HTML_PATTERN = /#{Regexp.union(*ESCAPE_HTML.keys)}/n + end # Escape ampersands, brackets and quotes to their HTML/XML entities. def escape_html(string) diff -Nru ruby-rack-1.3.1/metadata.yml ruby-rack-1.3.5/metadata.yml --- ruby-rack-1.3.1/metadata.yml 2011-07-25 15:56:14.000000000 +0000 +++ ruby-rack-1.3.5/metadata.yml 2011-10-22 04:16:19.000000000 +0000 @@ -1,13 +1,13 @@ --- !ruby/object:Gem::Specification name: rack version: !ruby/object:Gem::Version - hash: 25 + hash: 17 prerelease: segments: - 1 - 3 - - 1 - version: 1.3.1 + - 5 + version: 1.3.5 platform: ruby authors: - Christian Neukirchen @@ -15,7 +15,7 @@ bindir: bin cert_chain: [] -date: 2011-07-13 00:00:00 Z +date: 2011-10-18 00:00:00 Z dependencies: - !ruby/object:Gem::Dependency name: bacon @@ -81,10 +81,14 @@ requirements: - - ">=" - !ruby/object:Gem::Version - hash: 3 + hash: 1923831981 segments: + - 1 + - 2 - 0 - version: "0" + - pre + - 2 + version: 1.2.0.pre2 type: :development version_requirements: *id005 - !ruby/object:Gem::Dependency @@ -131,7 +135,8 @@ - lib/rack/auth/digest/nonce.rb - lib/rack/auth/digest/params.rb - lib/rack/auth/digest/request.rb -- lib/rack/backports/uri/common.rb +- lib/rack/backports/uri/common_18.rb +- lib/rack/backports/uri/common_192.rb - lib/rack/body_proxy.rb - lib/rack/builder.rb - lib/rack/cascade.rb @@ -301,7 +306,7 @@ requirements: [] rubyforge_project: rack -rubygems_version: 1.8.5 +rubygems_version: 1.8.11 signing_key: specification_version: 3 summary: a modular Ruby webserver interface diff -Nru ruby-rack-1.3.1/rack.gemspec ruby-rack-1.3.5/rack.gemspec --- ruby-rack-1.3.1/rack.gemspec 2011-07-25 15:56:14.000000000 +0000 +++ ruby-rack-1.3.5/rack.gemspec 2011-10-22 04:16:19.000000000 +0000 @@ -1,6 +1,6 @@ Gem::Specification.new do |s| s.name = "rack" - s.version = "1.3.1" + s.version = "1.3.5" s.platform = Gem::Platform::RUBY s.summary = "a modular Ruby webserver interface" @@ -32,6 +32,6 @@ s.add_development_dependency 'fcgi' s.add_development_dependency 'memcache-client' - s.add_development_dependency 'mongrel' + s.add_development_dependency 'mongrel', '>= 1.2.0.pre2' s.add_development_dependency 'thin' end diff -Nru ruby-rack-1.3.1/Rakefile ruby-rack-1.3.5/Rakefile --- ruby-rack-1.3.1/Rakefile 2011-07-25 15:56:14.000000000 +0000 +++ ruby-rack-1.3.5/Rakefile 2011-10-22 04:16:19.000000000 +0000 @@ -64,13 +64,13 @@ } end -desc "Run all the fast tests" +desc "Run all the fast + platform agnostic tests" task :test => 'SPEC' do opts = ENV['TEST'] || '-a' specopts = ENV['TESTOPTS'] || - "-q -t '^(?!Rack::Adapter|Rack::Session::Memcache|Rack::Server)'" + "-q -t '^(?!Rack::Adapter|Rack::Session::Memcache|Rack::Server|Rack::Handler)'" - sh "bacon -I./lib:./test -w #{opts} #{specopts}" + sh "bacon -I./lib:./test #{opts} #{specopts}" end desc "Run all the tests" diff -Nru ruby-rack-1.3.1/README.rdoc ruby-rack-1.3.5/README.rdoc --- ruby-rack-1.3.1/README.rdoc 2011-07-25 15:56:14.000000000 +0000 +++ ruby-rack-1.3.5/README.rdoc 2011-10-22 04:16:19.000000000 +0000 @@ -352,6 +352,27 @@ * Rack::MockResponse calls close on the body object * Fix a DOS vector from MRI stdlib backport +* July 16, 2011: Sixteenth public release 1.3.2 + * Fix for Rails and rack-test, Rack::Utils#escape calls to_s + +* September 16, 2011: Seventeenth public release 1.3.3 + * Fix bug with broken query parameters in Rack::ShowExceptions + * Rack::Request#cookies no longer swallows exceptions on broken input + * Prevents XSS attacks enabled by bug in Ruby 1.8's regexp engine + * Rack::ConditionalGet handles broken If-Modified-Since helpers + +* September 16, 2011: Eighteenth public release 1.2.4 + * Fix a bug with MRI regex engine to prevent XSS by malformed unicode + +* October 1, 2011: Nineteenth public release 1.3.4 + * Backport security fix from 1.9.3, also fixes some roundtrip issues in URI + * Small documentation update + * Fix an issue where BodyProxy could cause an infinite recursion + * Add some supporting files for travis-ci + +* October 17, 2011: Twentieth public release 1.3.5 + * Fix annoying warnings caused by the backport in 1.3.4 + == Contact Please post bugs, suggestions and patches to diff -Nru ruby-rack-1.3.1/test/spec_body_proxy.rb ruby-rack-1.3.5/test/spec_body_proxy.rb --- ruby-rack-1.3.1/test/spec_body_proxy.rb 2011-07-25 15:56:14.000000000 +0000 +++ ruby-rack-1.3.5/test/spec_body_proxy.rb 2011-10-22 04:16:19.000000000 +0000 @@ -35,9 +35,14 @@ should 'not close more than one time' do count = 0 proxy = Rack::BodyProxy.new([]) { count += 1; raise "Block invoked more than 1 time!" if count > 1 } + 2.times { proxy.close } + count.should.equal 1 + end + + should 'be closed when the callback is triggered' do + closed = false + proxy = Rack::BodyProxy.new([]) { closed = proxy.closed? } proxy.close - lambda { - proxy.close - }.should.raise(IOError) + closed.should.equal true end end diff -Nru ruby-rack-1.3.1/test/spec_conditionalget.rb ruby-rack-1.3.5/test/spec_conditionalget.rb --- ruby-rack-1.3.1/test/spec_conditionalget.rb 2011-07-25 15:56:14.000000000 +0000 +++ ruby-rack-1.3.5/test/spec_conditionalget.rb 2011-10-22 04:16:19.000000000 +0000 @@ -83,4 +83,16 @@ response.body.should.equal 'TEST' end + should "not affect requests with malformed HTTP_IF_NONE_MATCH" do + bad_timestamp = Time.now.strftime('%Y-%m-%d %H:%M:%S %z') + app = Rack::ConditionalGet.new(lambda { |env| + [200,{'Last-Modified'=>(Time.now - 3600).httpdate}, ['TEST']] }) + + response = Rack::MockRequest.new(app). + get("/", 'HTTP_IF_MODIFIED_SINCE' => bad_timestamp) + + response.status.should.equal 200 + response.body.should.equal 'TEST' + end + end diff -Nru ruby-rack-1.3.1/test/spec_mock.rb ruby-rack-1.3.5/test/spec_mock.rb --- ruby-rack-1.3.1/test/spec_mock.rb 2011-07-25 15:56:14.000000000 +0000 +++ ruby-rack-1.3.5/test/spec_mock.rb 2011-10-22 04:16:19.000000000 +0000 @@ -175,7 +175,8 @@ env["QUERY_STRING"].should.equal "" env["PATH_INFO"].should.equal "/foo" env["CONTENT_TYPE"].should.equal "multipart/form-data; boundary=AaB03x" - env["mock.postdata"].length.should.equal 206 + # The gsub accounts for differences in YAMLs affect on the data. + env["mock.postdata"].gsub("\r", "").length.should.equal 206 end should "behave valid according to the Rack spec" do diff -Nru ruby-rack-1.3.1/test/spec_request.rb ruby-rack-1.3.5/test/spec_request.rb --- ruby-rack-1.3.1/test/spec_request.rb 2011-07-25 15:56:14.000000000 +0000 +++ ruby-rack-1.3.5/test/spec_request.rb 2011-10-22 04:16:19.000000000 +0000 @@ -351,6 +351,19 @@ req.cookies.should.equal({}) end + should "always return the same hash object" do + req = Rack::Request.new \ + Rack::MockRequest.env_for("", "HTTP_COOKIE" => "foo=bar;quux=h&m") + hash = req.cookies + req.env.delete("HTTP_COOKIE") + req.cookies.should.equal(hash) + end + + should "raise any errors on every request" do + req = Rack::Request.new Rack::MockRequest.env_for("", "HTTP_COOKIE" => "foo=%") + 2.times { proc { req.cookies }.should.raise(ArgumentError) } + end + should "parse cookies according to RFC 2109" do req = Rack::Request.new \ Rack::MockRequest.env_for('', 'HTTP_COOKIE' => 'foo=bar;foo=car') diff -Nru ruby-rack-1.3.1/test/spec_utils.rb ruby-rack-1.3.5/test/spec_utils.rb --- ruby-rack-1.3.1/test/spec_utils.rb 2011-07-25 15:56:14.000000000 +0000 +++ ruby-rack-1.3.5/test/spec_utils.rb 2011-10-22 04:16:19.000000000 +0000 @@ -3,6 +3,14 @@ require 'rack/mock' describe Rack::Utils do + def kcodeu + one8 = RUBY_VERSION.to_f < 1.9 + default_kcode, $KCODE = $KCODE, 'U' if one8 + yield + ensure + $KCODE = default_kcode if one8 + end + should "escape correctly" do Rack::Utils.escape("fobar").should.equal "fo%3Co%3Ebar" Rack::Utils.escape("a space").should.equal "a+space" @@ -21,23 +29,27 @@ if RUBY_VERSION[/^\d+\.\d+/] == '1.8' should "escape correctly for multibyte characters if $KCODE is set to 'U'" do - default_kcode, $KCODE = $KCODE, 'U' - - matz_name = "\xE3\x81\xBE\xE3\x81\xA4\xE3\x82\x82\xE3\x81\xA8".unpack("a*")[0] # Matsumoto - matz_name.force_encoding("UTF-8") if matz_name.respond_to? :force_encoding - Rack::Utils.escape(matz_name).should.equal '%E3%81%BE%E3%81%A4%E3%82%82%E3%81%A8' - matz_name_sep = "\xE3\x81\xBE\xE3\x81\xA4 \xE3\x82\x82\xE3\x81\xA8".unpack("a*")[0] # Matsu moto - matz_name_sep.force_encoding("UTF-8") if matz_name_sep.respond_to? :force_encoding - Rack::Utils.escape(matz_name_sep).should.equal '%E3%81%BE%E3%81%A4+%E3%82%82%E3%81%A8' - - $KCODE = default_kcode + kcodeu do + matz_name = "\xE3\x81\xBE\xE3\x81\xA4\xE3\x82\x82\xE3\x81\xA8".unpack("a*")[0] # Matsumoto + matz_name.force_encoding("UTF-8") if matz_name.respond_to? :force_encoding + Rack::Utils.escape(matz_name).should.equal '%E3%81%BE%E3%81%A4%E3%82%82%E3%81%A8' + matz_name_sep = "\xE3\x81\xBE\xE3\x81\xA4 \xE3\x82\x82\xE3\x81\xA8".unpack("a*")[0] # Matsu moto + matz_name_sep.force_encoding("UTF-8") if matz_name_sep.respond_to? :force_encoding + Rack::Utils.escape(matz_name_sep).should.equal '%E3%81%BE%E3%81%A4+%E3%82%82%E3%81%A8' + end end should "unescape multibyte characters correctly if $KCODE is set to 'U'" do - default_kcode, $KCODE = $KCODE, 'U' - Rack::Utils.unescape('%E3%81%BE%E3%81%A4+%E3%82%82%E3%81%A8').should.equal( + kcodeu do + Rack::Utils.unescape('%E3%81%BE%E3%81%A4+%E3%82%82%E3%81%A8').should.equal( "\xE3\x81\xBE\xE3\x81\xA4 \xE3\x82\x82\xE3\x81\xA8".unpack("a*")[0]) - $KCODE = default_kcode + end + end + end + + should "escape objects that responds to to_s" do + kcodeu do + Rack::Utils.escape(:id).should.equal "id" end end @@ -46,6 +58,16 @@ Rack::Utils.escape("ø".encode("ISO-8859-1")).should.equal "%F8" end end + + should "not hang on escaping long strings that end in % (http://redmine.ruby-lang.org/issues/5149)" do + lambda { + timeout(1) do + lambda { + URI.decode_www_form_component "A string that causes catastrophic backtracking as it gets longer %" + }.should.raise(ArgumentError) + end + }.should.not.raise(Timeout::Error) + end should "escape path spaces with %20" do Rack::Utils.escape_path("foo bar").should.equal "foo%20bar" @@ -211,7 +233,7 @@ message.should.equal "value must be a Hash" end - should "should escape html entities [&><'\"/]" do + should "escape html entities [&><'\"/]" do Rack::Utils.escape_html("foo").should.equal "foo" Rack::Utils.escape_html("f&o").should.equal "f&o" Rack::Utils.escape_html("f").should.equal "<foo></foo>" end + should "escape html entities even on MRI when it's bugged" do + test_escape = lambda do + kcodeu do + Rack::Utils.escape_html("\300<").should.equal "\300<" + end + end + + if RUBY_VERSION.to_f < 1.9 + test_escape.call + else + test_escape.should.raise(ArgumentError) + end + end + + if "".respond_to?(:encode) + should "escape html entities in unicode strings" do + # the following will cause warnings if the regex is poorly encoded: + Rack::Utils.escape_html("☃").should.equal "☃" + end + end + should "figure out which encodings are acceptable" do helper = lambda do |a, b| Rack::Request.new(Rack::MockRequest.env_for("", "HTTP_ACCEPT_ENCODING" => a))