Commit ba692558 authored by Antonio Terceiro's avatar Antonio Terceiro

Imported Upstream version 4.1.10

parent ee1dd1e7
......@@ -5,7 +5,6 @@ debug.log
.Gemfile
/.bundle
/.ruby-version
/Gemfile.lock
pkg
/dist
/doc/rdoc
......
language: ruby
sudo: false
script: 'ci/travis.rb'
before_install:
- travis_retry gem install bundler
- "rvm current | grep 'jruby' && export AR_JDBC=true || echo"
- "rm ${BUNDLE_GEMFILE}.lock"
before_script:
- bundle update
cache: bundler
rvm:
- 1.9.3
- 2.0.0
- 2.1
- 2.2
- ruby-head
- rbx-2
- jruby
......@@ -34,6 +40,6 @@ notifications:
on_failure: always
rooms:
- secure: "YA1alef1ESHWGFNVwvmVGCkMe4cUy4j+UcNvMUESraceiAfVyRMAovlQBGs6\n9kBRm7DHYBUXYC2ABQoJbQRLDr/1B5JPf/M8+Qd7BKu8tcDC03U01SMHFLpO\naOs/HLXcDxtnnpL07tGVsm0zhMc5N8tq4/L3SHxK7Vi+TacwQzI="
bundler_args: --path vendor/bundle --without test
bundler_args: --without test --jobs 3 --retry 3
services:
- memcached
......@@ -25,7 +25,8 @@ group :doc do
gem 'sdoc', '~> 0.4.0'
gem 'redcarpet', '~> 2.2.2', platforms: :ruby
gem 'w3c_validators'
gem 'kindlerb'
gem 'kindlerb', '0.1.1'
gem 'mustache', '~> 0.99.8'
end
# AS
......
PATH
remote: .
specs:
actionmailer (4.1.10.rc1)
actionpack (= 4.1.10.rc1)
actionview (= 4.1.10.rc1)
mail (~> 2.5, >= 2.5.4)
actionpack (4.1.10.rc1)
actionview (= 4.1.10.rc1)
activesupport (= 4.1.10.rc1)
rack (~> 1.5.2)
rack-test (~> 0.6.2)
actionview (4.1.10.rc1)
activesupport (= 4.1.10.rc1)
builder (~> 3.1)
erubis (~> 2.7.0)
activemodel (4.1.10.rc1)
activesupport (= 4.1.10.rc1)
builder (~> 3.1)
activerecord (4.1.10.rc1)
activemodel (= 4.1.10.rc1)
activesupport (= 4.1.10.rc1)
arel (~> 5.0.0)
activesupport (4.1.10.rc1)
i18n (~> 0.6, >= 0.6.9)
json (~> 1.7, >= 1.7.7)
minitest (~> 5.1)
thread_safe (~> 0.1)
tzinfo (~> 1.1)
rails (4.1.10.rc1)
actionmailer (= 4.1.10.rc1)
actionpack (= 4.1.10.rc1)
actionview (= 4.1.10.rc1)
activemodel (= 4.1.10.rc1)
activerecord (= 4.1.10.rc1)
activesupport (= 4.1.10.rc1)
bundler (>= 1.3.0, < 2.0)
railties (= 4.1.10.rc1)
sprockets-rails (~> 2.0)
railties (4.1.10.rc1)
actionpack (= 4.1.10.rc1)
activesupport (= 4.1.10.rc1)
rake (>= 0.8.7)
thor (>= 0.18.1, < 2.0)
GEM
remote: https://rubygems.org/
specs:
arel (5.0.1.20140414130214)
bcrypt (3.1.10)
benchmark-ips (2.1.1)
builder (3.2.2)
coffee-rails (4.0.1)
coffee-script (>= 2.2.0)
railties (>= 4.0.0, < 5.0)
coffee-script (2.3.0)
coffee-script-source
execjs
coffee-script-source (1.9.0)
dalli (2.7.2)
erubis (2.7.0)
execjs (2.3.0)
hike (1.2.3)
i18n (0.7.0)
jquery-rails (3.1.2)
railties (>= 3.0, < 5.0)
thor (>= 0.14, < 2.0)
json (1.8.2)
kindlerb (0.1.1)
mustache
nokogiri
mail (2.6.3)
mime-types (>= 1.16, < 3)
metaclass (0.0.4)
mime-types (2.4.3)
mini_portile (0.6.2)
minitest (5.3.3)
mocha (0.14.0)
metaclass (~> 0.0.1)
multi_json (1.10.1)
mustache (0.99.8)
mysql (2.9.1)
mysql2 (0.3.18)
nokogiri (1.6.6.2)
mini_portile (~> 0.6.0)
pg (0.18.1)
racc (1.4.12)
rack (1.5.2)
rack-cache (1.2)
rack (>= 0.4)
rack-test (0.6.3)
rack (>= 1.0)
rake (10.4.2)
rdoc (4.2.0)
redcarpet (2.2.2)
ruby-prof (0.11.3)
sdoc (0.4.1)
json (~> 1.7, >= 1.7.7)
rdoc (~> 4.0)
sprockets (2.12.3)
hike (~> 1.2)
multi_json (~> 1.0)
rack (~> 1.0)
tilt (~> 1.1, != 1.3.0)
sprockets-rails (2.2.4)
actionpack (>= 3.0)
activesupport (>= 3.0)
sprockets (>= 2.8, < 4.0)
sqlite3 (1.3.10)
thor (0.19.1)
thread_safe (0.3.4)
tilt (1.4.1)
turbolinks (2.5.3)
coffee-rails
tzinfo (1.2.2)
thread_safe (~> 0.1)
uglifier (2.7.0)
execjs (>= 0.3.0)
json (>= 1.8.0)
w3c_validators (1.2)
json
nokogiri
PLATFORMS
ruby
DEPENDENCIES
activerecord-jdbcmysql-adapter (>= 1.3.0)
activerecord-jdbcpostgresql-adapter (>= 1.3.0)
activerecord-jdbcsqlite3-adapter (>= 1.3.0)
bcrypt (~> 3.1.7)
benchmark-ips
coffee-rails (~> 4.0.0)
dalli (>= 2.2.1)
jquery-rails (~> 3.1.0)
json
kindlerb (= 0.1.1)
minitest (< 5.3.4)
mocha (~> 0.14)
mustache (~> 0.99.8)
mysql (>= 2.9.0)
mysql2 (>= 0.3.13)
nokogiri (>= 1.4.5)
pg (>= 0.11.0)
racc (>= 1.4.6)
rack-cache (~> 1.2)
rails!
redcarpet (~> 2.2.2)
ruby-prof (~> 0.11.2)
sdoc (~> 0.4.0)
sqlite3 (~> 1.3.6)
turbolinks
uglifier (>= 1.3.0)
w3c_validators
## Rails 4.1.10 (March 19, 2015) ##
* No changes.
## Rails 4.1.9 (January 6, 2015) ##
* No changes.
## Rails 4.1.8 (November 16, 2014) ##
* Attachments can be added while rendering the mail template.
Fixes #16974.
*Christian Felder*
## Rails 4.1.7.1 (November 19, 2014) ##
* No changes.
## Rails 4.1.7 (October 29, 2014) ##
* No changes.
## Rails 4.1.6 (September 11, 2014) ##
* Make ActionMailer::Previews methods class methods. Previously they were
......
......@@ -7,7 +7,7 @@ def self.gem_version
module VERSION
MAJOR = 4
MINOR = 1
TINY = 8
TINY = 10
PRE = nil
STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
......
## Rails 4.1.10 (March 19, 2015) ##
* Preserve default format when generating URLs
Fixes an issue that would cause the format set in default_url_options to be
lost when generating URLs with fewer positional arguments than parameters in
the route definition.
Backport of #18627
*Tekin Suleyman*, *Dominic Baggott*
* Default headers, removed in controller actions, are no longer reapplied on
the test response.
*Jonas Baumann*
* Ensure `append_info_to_payload` is called even if an exception is raised.
Fixes an issue where when an exception is raised in the request the additonal
payload data is not available.
See:
* #14903
* https://github.com/roidrage/lograge/issues/37
*Dieter Komendera*, *Margus Pärt*
## Rails 4.1.9 (January 6, 2015) ##
* Fixed handling of positional url helper arguments when `format: false`.
Fixes #17819.
*Andrew White*, *Tatiana Soukiassian*
* Restore handling of a bare `Authorization` header, without `token=`
prefix.
Fixes #17108.
*Guo Xiang Tan*
## Rails 4.1.8 (November 16, 2014) ##
* Fix regression where path was getting overwritten when route anchor was false, and X-Cascade pass
fixes #17035.
......@@ -11,6 +58,20 @@
*Yuki Nishijima*
## Rails 4.1.7.1 (November 19, 2014) ##
* Fix arbitrary file existence disclosure in Action Pack.
CVE-2014-7829.
## Rails 4.1.7 (October 29, 2014) ##
* Fix arbitrary file existence disclosure in Action Pack.
CVE-2014-7818.
## Rails 4.1.6 (September 11, 2014) ##
* Prepend a JS comment to JSONP callbacks. Addresses CVE-2014-4671
......
......@@ -44,7 +44,7 @@ module ActionController
# The full request object is available via the request accessor and is primarily used to query for HTTP headers:
#
# def server_ip
# location = request.env["SERVER_ADDR"]
# location = request.env["REMOTE_ADDR"]
# render plain: "This server hosted at #{location}"
# end
#
......
......@@ -397,6 +397,7 @@ def opaque(secret_key)
#
# RewriteRule ^(.*)$ dispatch.fcgi [E=X-HTTP_AUTHORIZATION:%{HTTP:Authorization},QSA,L]
module Token
TOKEN_KEY = 'token='
TOKEN_REGEX = /^Token /
AUTHN_PAIR_DELIMITERS = /(?:,|;|\t+)/
extend self
......@@ -471,7 +472,13 @@ def rewrite_param_values(array_params)
# pairs by the standardized `:`, `;`, or `\t` delimiters defined in
# `AUTHN_PAIR_DELIMITERS`.
def raw_params(auth)
auth.sub(TOKEN_REGEX, '').split(/"\s*#{AUTHN_PAIR_DELIMITERS}\s*/)
_raw_params = auth.sub(TOKEN_REGEX, '').split(/\s*#{AUTHN_PAIR_DELIMITERS}\s*/)
if !(_raw_params.first =~ %r{\A#{TOKEN_KEY}})
_raw_params[0] = "#{TOKEN_KEY}#{_raw_params.first}"
end
_raw_params
end
# Encodes the given token and options into an Authorization header value.
......@@ -481,7 +488,7 @@ def raw_params(auth)
#
# Returns String.
def encode_credentials(token, options = {})
values = ["token=#{token.to_s.inspect}"] + options.map do |key, value|
values = ["#{TOKEN_KEY}#{token.to_s.inspect}"] + options.map do |key, value|
"#{key}=#{value.to_s.inspect}"
end
"Token #{values * ", "}"
......
......@@ -28,10 +28,13 @@ def process_action(*args)
ActiveSupport::Notifications.instrument("start_processing.action_controller", raw_payload.dup)
ActiveSupport::Notifications.instrument("process_action.action_controller", raw_payload) do |payload|
result = super
payload[:status] = response.status
append_info_to_payload(payload)
result
begin
result = super
payload[:status] = response.status
result
ensure
append_info_to_payload(payload)
end
end
end
......
......@@ -70,7 +70,7 @@ def formats
def variant=(variant)
if variant.is_a?(Symbol)
@variant = [variant]
elsif variant.is_a?(Array) && variant.any? && variant.all?{ |v| v.is_a?(Symbol) }
elsif variant.nil? || variant.is_a?(Array) && variant.any? && variant.all?{ |v| v.is_a?(Symbol) }
@variant = variant
else
raise ArgumentError, "request.variant must be set to a Symbol or an Array of Symbols, not a #{variant.class}. " \
......
......@@ -56,7 +56,7 @@ def call(original_params)
elsif value.is_a?(Array)
value = value.map { |v| v.is_a?(Hash) ? call(v) : v }
elsif blocks.any?
key = key.dup
key = key.dup if key.duplicable?
value = value.dup if value.duplicable?
blocks.each { |b| b.call(key, value) }
end
......
......@@ -70,11 +70,13 @@ def cookie_jar
# restrict to the domain level. If you use a schema like www.example.com
# and want to share session with user.example.com set <tt>:domain</tt>
# to <tt>:all</tt>. Make sure to specify the <tt>:domain</tt> option with
# <tt>:all</tt> again when deleting cookies.
# <tt>:all</tt> or <tt>Array</tt> again when deleting cookies.
#
# domain: nil # Does not sets cookie domain. (default)
# domain: :all # Allow the cookie for the top most level
# domain and subdomains.
# domain: %w(.example.com .example.org) # Allow the cookie
# for concrete domain names.
#
# * <tt>:expires</tt> - The time at which this cookie expires, as a \Time object.
# * <tt>:secure</tt> - Whether this cookie is only transmitted to HTTPS servers.
......@@ -118,7 +120,7 @@ def permanent
# the cookie again. This is useful for creating cookies with values that the user is not supposed to change. If a signed
# cookie was tampered with by the user (or a 3rd party), nil will be returned.
#
# If +secrets.secret_key_base+ and +config.secret_token+ (deprecated) are both set,
# If +secrets.secret_key_base+ and +secrets.secret_token+ (deprecated) are both set,
# legacy cookies signed with the old key generator will be transparently upgraded.
#
# This jar requires that you set a suitable secret for the verification on your app's +secrets.secret_key_base+.
......@@ -141,7 +143,7 @@ def signed
# Returns a jar that'll automatically encrypt cookie values before sending them to the client and will decrypt them for read.
# If the cookie was tampered with by the user (or a 3rd party), nil will be returned.
#
# If +secrets.secret_key_base+ and +config.secret_token+ (deprecated) are both set,
# If +secrets.secret_key_base+ and +secrets.secret_token+ (deprecated) are both set,
# legacy cookies signed with the old key generator will be transparently upgraded.
#
# This jar requires that you set a suitable secret for the verification on your app's +secrets.secret_key_base+.
......@@ -481,7 +483,7 @@ def verify(signed_message)
end
# UpgradeLegacySignedCookieJar is used instead of SignedCookieJar if
# config.secret_token and secrets.secret_key_base are both set. It reads
# secrets.secret_token and secrets.secret_key_base are both set. It reads
# legacy cookies signed with the old dummy key generator and re-saves
# them using the new key generator to provide a smooth upgrade path.
class UpgradeLegacySignedCookieJar < SignedCookieJar #:nodoc:
......@@ -539,7 +541,7 @@ def decrypt_and_verify(encrypted_message)
end
# UpgradeLegacyEncryptedCookieJar is used by ActionDispatch::Session::CookieStore
# instead of EncryptedCookieJar if config.secret_token and secrets.secret_key_base
# instead of EncryptedCookieJar if secrets.secret_token and secrets.secret_key_base
# are both set. It reads legacy cookies signed with the old dummy key generator and
# encrypts and re-saves them using the new key generator to provide a smooth upgrade path.
class UpgradeLegacyEncryptedCookieJar < EncryptedCookieJar #:nodoc:
......
......@@ -129,7 +129,7 @@ def keys
end
def key?(name)
@flashes.key? name
@flashes.key? name.to_s
end
def delete(key)
......
......@@ -235,12 +235,26 @@ def handle_positional_args(t, args, options, keys)
result = options.dup
if args.size > 0
if args.size < keys.size - 1 # take format into account
# take format into account
if keys.include?(:format)
keys_size = keys.size - 1
else
keys_size = keys.size
end
if args.size < keys_size
keys -= t.url_options.keys if t.respond_to?(:url_options)
keys -= options.keys
end
keys -= inner_options.keys
result.merge!(Hash[keys.zip(args)])
keys.each do |key|
value = inner_options.fetch(key) { args.shift }
unless key == :format && value.nil?
result[key] = value
end
end
end
result.merge!(inner_options)
......
......@@ -25,5 +25,12 @@ def self.from_response(response)
# Was there a server-side error?
alias_method :error?, :server_error?
def merge_default_headers(original, *args)
# Default headers are already applied, no need to merge them a second time.
# This makes sure that default headers, removed in controller actions, will
# not be reapplied to the test response.
original
end
end
end
......@@ -7,7 +7,7 @@ def self.gem_version
module VERSION
MAJOR = 4
MINOR = 1
TINY = 8
TINY = 10
PRE = nil
STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
......
......@@ -51,6 +51,22 @@ def default_url_options
end
end
class OptionalDefaultUrlOptionsController < ActionController::Base
def default_url_options
{ thing: 'default_thing' }
end
end
class DefaultFormatController < ActionController::Base
def show
render nothing: true
end
def default_url_options
{ format: 'atom' }
end
end
class UrlOptionsController < ActionController::Base
def from_view
render :inline => "<%= #{params[:route]} %>"
......@@ -274,6 +290,30 @@ def test_default_url_options_are_used_in_non_positional_parameters
end
class DefaultFormatControllerTest < ActionController::TestCase
def test_default_format_preserved_when_missing_from_positional_arguments
with_routing do |set|
set.draw do
get "/things/:id(.:format)" => 'default_format#show', :as => :thing
end
assert_equal '/things/1.atom', thing_path("1")
end
end
end
class OptionalDefaultUrlOptionsControllerTest < ActionController::TestCase
def test_optional_default_url_options_are_overridden_by_missing_positional_args
with_routing do |set|
set.draw do
get "/:category(/:thing)" => "optional_default_url_options#show", :as => :thing
end
assert_equal "/things/a_thing", thing_path('things', 'a_thing')
assert_equal "/things/default_thing", thing_path('things')
end
end
end
class EmptyUrlOptionsTest < ActionController::TestCase
tests NonEmptyController
......
......@@ -29,6 +29,15 @@ def test_update
assert_equal 'world', @hash['hello']
end
def test_key
@hash['foo'] = 'bar'
assert @hash.key?('foo')
assert @hash.key?(:foo)
assert_not @hash.key?('bar')
assert_not @hash.key?(:bar)
end
def test_delete
@hash['foo'] = 'bar'
@hash.delete 'foo'
......
......@@ -139,20 +139,59 @@ def authenticate_long_credentials
assert_equal(expected, actual)
end
test "token_and_options returns correct token with nounce option" do
token = "rcHu+HzSFw89Ypyhn/896A="
nonce_hash = {nonce: "123abc"}
actual = ActionController::HttpAuthentication::Token.token_and_options(sample_request(token, nonce_hash))
expected_token = token
expected_nonce = {"nonce" => nonce_hash[:nonce]}
assert_equal(expected_token, actual.first)
assert_equal(expected_nonce, actual.last)
end
test "token_and_options returns nil with no value after the equal sign" do
actual = ActionController::HttpAuthentication::Token.token_and_options(malformed_request).first
expected = nil
assert_equal(expected, actual)
end
test "raw_params returns a tuple of two key value pair strings" do
auth = sample_request("rcHu+HzSFw89Ypyhn/896A=").authorization.to_s
actual = ActionController::HttpAuthentication::Token.raw_params(auth)
expected = ["token=\"rcHu+HzSFw89Ypyhn/896A=\"", "nonce=\"def\""]
assert_equal(expected, actual)
end
test "token_and_options returns right token when token key is not specified in header" do
token = "rcHu+HzSFw89Ypyhn/896A="
actual = ActionController::HttpAuthentication::Token.token_and_options(
sample_request_without_token_key(token)
).first
expected = token
assert_equal(expected, actual)
end
private
def sample_request(token)
@sample_request ||= OpenStruct.new authorization: %{Token token="#{token}", nonce="def"}
def sample_request(token, options = {nonce: "def"})
authorization = options.inject([%{Token token="#{token}"}]) do |arr, (k, v)|
arr << "#{k}=\"#{v}\""
end.join(", ")
mock_authorization_request(authorization)
end
def malformed_request
@malformed_request ||= OpenStruct.new authorization: %{Token token=}
mock_authorization_request(%{Token token=})
end
def sample_request_without_token_key(token)
mock_authorization_request(%{Token #{token}})
end
def mock_authorization_request(authorization)
OpenStruct.new(authorization: authorization)
end
def encode_credentials(token, options = {})
......
......@@ -279,6 +279,11 @@ def get_cookie
def redirect
redirect_to action_url('get')
end
def remove_default_header
response.headers.except! 'X-Frame-Options'
head :ok
end
end
def test_get
......@@ -506,6 +511,24 @@ def test_https_and_port_via_process
end
end
def test_removed_default_headers_on_test_response_are_not_reapplied
with_test_route_set do
begin
header_to_remove = 'X-Frame-Options'
original_default_headers = ActionDispatch::Response.default_headers
ActionDispatch::Response.default_headers = {
'X-Content-Type-Options' => 'nosniff',
header_to_remove => 'SAMEORIGIN',
}
get '/remove_default_header'
assert_includes headers, 'X-Content-Type-Options'
assert_not_includes headers, header_to_remove, "Should not contain removed default header"
ensure
ActionDispatch::Response.default_headers = original_default_headers
end
end
end
private
def with_test_route_set
with_routing do |set|
......
......@@ -73,6 +73,16 @@ def with_rescued_exception