Permalink
Browse files

Merge tag 'v3.2.18' into 3-2-stable

  • Loading branch information...
2 parents 8da1e61 + 50d6b45 commit cec1ae5f3e29b2d901a465afbaf4e353cad2e2a1 @willbryant committed May 6, 2014
Showing with 646 additions and 149 deletions.
  1. +1 −1 Gemfile
  2. +1 −1 RAILS_VERSION
  3. +20 −1 actionmailer/CHANGELOG.md
  4. +3 −3 actionmailer/lib/action_mailer/log_subscriber.rb
  5. +1 −1 actionmailer/lib/action_mailer/version.rb
  6. +65 −1 actionpack/CHANGELOG.md
  7. +25 −3 actionpack/lib/abstract_controller/base.rb
  8. +5 −6 actionpack/lib/action_controller/log_subscriber.rb
  9. +2 −2 actionpack/lib/action_dispatch/http/request.rb
  10. +1 −1 actionpack/lib/action_dispatch/middleware/remote_ip.rb
  11. +2 −1 actionpack/lib/action_dispatch/routing/route_set.rb
  12. +1 −1 actionpack/lib/action_dispatch/testing/assertions/response.rb
  13. +3 −3 actionpack/lib/action_dispatch/testing/assertions/routing.rb
  14. +1 −1 actionpack/lib/action_pack/version.rb
  15. +14 −2 actionpack/lib/action_view/helpers/number_helper.rb
  16. +8 −13 actionpack/lib/action_view/helpers/translation_helper.rb
  17. +9 −5 actionpack/lib/action_view/lookup_context.rb
  18. +0 −6 actionpack/lib/action_view/renderer/abstract_renderer.rb
  19. +0 −2 actionpack/lib/action_view/renderer/partial_renderer.rb
  20. +2 −3 actionpack/lib/action_view/renderer/template_renderer.rb
  21. +1 −1 actionpack/lib/action_view/template/text.rb
  22. +16 −1 actionpack/test/controller/new_base/render_implicit_action_test.rb
  23. +15 −0 actionpack/test/dispatch/request/query_string_parsing_test.rb
  24. +13 −1 actionpack/test/dispatch/routing_assertions_test.rb
  25. +0 −1 actionpack/test/fixtures/test/_changing_priority.html.erb
  26. +0 −1 actionpack/test/fixtures/test/_changing_priority.json.erb
  27. +0 −1 actionpack/test/fixtures/test/_first_json_partial.json.erb
  28. 0 actionpack/test/fixtures/test/_json_change_priority.json.erb
  29. +0 −1 actionpack/test/fixtures/test/_second_json_partial.json.erb
  30. +0 −1 actionpack/test/fixtures/test/html_template.html.erb
  31. +0 −32 actionpack/test/metal/caching_test.rb
  32. +5 −5 actionpack/test/template/number_helper_i18n_test.rb
  33. +55 −3 actionpack/test/template/number_helper_test.rb
  34. +7 −10 actionpack/test/template/render_test.rb
  35. +17 −0 actionpack/test/template/text_test.rb
  36. +1 −1 actionpack/test/template/translation_helper_test.rb
  37. +20 −1 activemodel/CHANGELOG.md
  38. +1 −1 activemodel/lib/active_model/version.rb
  39. +57 −1 activerecord/CHANGELOG.md
  40. +6 −4 activerecord/lib/active_record/associations/collection_proxy.rb
  41. +1 −0 activerecord/lib/active_record/associations/has_many_association.rb
  42. +2 −0 activerecord/lib/active_record/autosave_association.rb
  43. +2 −2 activerecord/lib/active_record/connection_adapters/schema_cache.rb
  44. +2 −2 activerecord/lib/active_record/fixtures.rb
  45. +1 −1 activerecord/lib/active_record/locking/optimistic.rb
  46. +2 −2 activerecord/lib/active_record/relation/finder_methods.rb
  47. +4 −3 activerecord/lib/active_record/relation/spawn_methods.rb
  48. +1 −1 activerecord/lib/active_record/version.rb
  49. +20 −0 activerecord/test/cases/associations/has_many_associations_test.rb
  50. +7 −0 activerecord/test/cases/autosave_association_test.rb
  51. +14 −0 activerecord/test/cases/finder_test.rb
  52. +1 −1 activerecord/test/cases/fixtures_test.rb
  53. +5 −0 activerecord/test/cases/inheritance_test.rb
  54. +12 −0 activerecord/test/cases/locking_test.rb
  55. +15 −0 activerecord/test/cases/relations_test.rb
  56. +1 −0 activerecord/test/fixtures/all/admin
  57. +11 −1 activerecord/test/models/company.rb
  58. +23 −1 activeresource/CHANGELOG.md
  59. +1 −1 activeresource/lib/active_resource/version.rb
  60. +28 −2 activesupport/CHANGELOG.md
  61. +2 −1 activesupport/lib/active_support/cache/file_store.rb
  62. +4 −0 activesupport/lib/active_support/log_subscriber.rb
  63. +10 −0 activesupport/lib/active_support/tagged_logging.rb
  64. +1 −1 activesupport/lib/active_support/version.rb
  65. +12 −0 activesupport/test/caching_test.rb
  66. +4 −0 activesupport/test/tagged_logging_test.rb
  67. +21 −1 railties/CHANGELOG.md
  68. +1 −1 railties/guides/rails_guides.rb
  69. +1 −1 railties/lib/rails/generators/rails/app/app_generator.rb
  70. +2 −2 railties/lib/rails/tasks/documentation.rake
  71. +1 −1 railties/lib/rails/version.rb
  72. +10 −0 railties/test/application/middleware/remote_ip_test.rb
  73. +45 −0 railties/test/application/routing_test.rb
  74. +1 −1 version.rb
View
@@ -22,7 +22,7 @@ end
gem 'uglifier', '>= 1.0.3', :require => false
gem 'rake', '>= 0.8.7'
-gem 'mocha', '>= 0.13.0', :require => false
+gem 'mocha', '~> 0.14', :require => false
group :doc do
# The current sdoc cannot generate GitHub links due
View
@@ -1 +1 @@
-3.2.13
+3.2.18
View
@@ -1,4 +1,23 @@
-## unreleased ##
+## Rails 3.2.18 (May 6, 2014) ##
+
+* No changes.
+
+
+## Rails 3.2.17 (Feb 18, 2014) ##
+
+* No changes.
+
+
+## Rails 3.2.16 (Dec 3, 2013) ##
+
+* No changes.
+
+
+## Rails 3.2.15 (Oct 16, 2013) ##
+
+* No changes.
+
+## Rails 3.2.14 (Jul 22, 2013) ##
* No changes.
@@ -4,12 +4,12 @@ module ActionMailer
class LogSubscriber < ActiveSupport::LogSubscriber
def deliver(event)
recipients = Array.wrap(event.payload[:to]).join(', ')
- info("\nSent mail to #{recipients} (%1.fms)" % event.duration)
+ info("\nSent mail to #{recipients} (#{format_duration(event.duration)})")
debug(event.payload[:mail])
end
def receive(event)
- info("\nReceived mail (%.1fms)" % event.duration)
+ info("\nReceived mail (#{format_duration(event.duration)})")
debug(event.payload[:mail])
end
@@ -19,4 +19,4 @@ def logger
end
end
-ActionMailer::LogSubscriber.attach_to :action_mailer
+ActionMailer::LogSubscriber.attach_to :action_mailer
@@ -2,7 +2,7 @@ module ActionMailer
module VERSION #:nodoc:
MAJOR = 3
MINOR = 2
- TINY = 13
+ TINY = 18
PRE = nil
STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
View
@@ -1,4 +1,68 @@
-## unreleased ##
+## Rails 3.2.18 (May 6, 2014) ##
+
+* Only accept actions without File::SEPARATOR in the name.
+
+ This will avoid directory traversal in implicit render.
+
+ Fixes: CVE-2014-0130
+
+ *Rafael Mendonça França*
+
+
+## Rails 3.2.17 (Feb 18, 2014) ##
+
+* Use the reference for the mime type to get the format
+
+ Fixes: CVE-2014-0082
+
+* Escape format, negative_format and units options of number helpers
+
+ Fixes: CVE-2014-0081
+
+
+## Rails 3.2.16 (Dec 12, 2013) ##
+
+* Deep Munge the parameters for GET and POST Fixes CVE-2013-6417
+
+* Stop using i18n's built in HTML error handling. Fixes: CVE-2013-4491
+
+* Escape the unit value provided to number_to_currency Fixes CVE-2013-6415
+
+* Only use valid mime type symbols as cache keys CVE-2013-6414
+
+## Rails 3.2.15 (Oct 16, 2013) ##
+
+* Fix `ActionDispatch::RemoteIp::GetIp#calculate_ip` to only check for spoofing
+ attacks if both `HTTP_CLIENT_IP` and `HTTP_X_FORWARDED_FOR` are set.
+
+ Fixes #12410
+ Backports #10844
+
+ *Tamir Duberstein*
+
+* Fix the assert_recognizes test method so that it works when there are
+ constraints on the querystring.
+
+ Issue/Pull Request #9368
+ Backport #5219
+
+ *Brian Hahn*
+
+* Fix to render partial by context(#11605).
+
+ *Kassio Borges*
+
+* Fix `ActionDispatch::Assertions::ResponseAssertions#assert_redirected_to`
+ does not show user-supplied message.
+
+ Issue: when `assert_redirected_to` fails due to the response redirect not
+ matching the expected redirect the user-supplied message (second parameter)
+ is not shown. This message is only shown if the response is not a redirect.
+
+ *Alexey Chernenkov*
+
+
+## Rails 3.2.14 (Jul 22, 2013) ##
* Merge `:action` from routing scope and assign endpoint if both `:controller`
and `:action` are present. The endpoint assignment only occurs if there is
@@ -112,7 +112,7 @@ def method_added(name)
def process(action, *args)
@_action_name = action_name = action.to_s
- unless action_name = method_for_action(action_name)
+ unless action_name = _find_action_name(action_name)
raise ActionNotFound, "The action '#{action}' could not be found for #{self.class.name}"
end
@@ -138,7 +138,7 @@ def action_methods
# available action consider actions that are also available
# through other means, for example, implicit render ones.
def available_action?(action_name)
- method_for_action(action_name).present?
+ _find_action_name(action_name).present?
end
private
@@ -181,6 +181,23 @@ def _handle_action_missing(*args)
action_missing(@_action_name, *args)
end
+ # Takes an action name and returns the name of the method that will
+ # handle the action.
+ #
+ # It checks if the action name is valid and returns false otherwise.
+ #
+ # See method_for_action for more information.
+ #
+ # ==== Parameters
+ # * <tt>action_name</tt> - An action name to find a method name for
+ #
+ # ==== Returns
+ # * <tt>string</tt> - The name of the method that handles the action
+ # * false - No valid method name could be found. Raise ActionNotFound.
+ def _find_action_name(action_name)
+ _valid_action_name?(action_name) && method_for_action(action_name)
+ end
+
# Takes an action name and returns the name of the method that will
# handle the action. In normal cases, this method returns the same
# name as it receives. By default, if #method_for_action receives
@@ -203,11 +220,16 @@ def _handle_action_missing(*args)
#
# ==== Returns
# * <tt>string</tt> - The name of the method that handles the action
- # * <tt>nil</tt> - No method name could be found. Raise ActionNotFound.
+ # * <tt>nil</tt> - No method name could be found.
def method_for_action(action_name)
if action_method?(action_name) then action_name
elsif respond_to?(:action_missing, true) then "_handle_action_missing"
end
end
+
+ # Checks if the action name is valid and returns false otherwise.
+ def _valid_action_name?(action_name)
+ action_name.to_s !~ Regexp.new(File::SEPARATOR)
+ end
end
end
@@ -23,7 +23,7 @@ def process_action(event)
exception_class_name = payload[:exception].first
status = ActionDispatch::ExceptionWrapper.status_code_for_exception(exception_class_name)
end
- message = "Completed #{status} #{Rack::Utils::HTTP_STATUS_CODES[status]} in %.0fms" % event.duration
+ message = "Completed #{status} #{Rack::Utils::HTTP_STATUS_CODES[status]} in #{format_duration(event.duration)}"
message << " (#{additions.join(" | ")})" unless additions.blank?
info(message)
@@ -34,17 +34,15 @@ def halted_callback(event)
end
def send_file(event)
- message = "Sent file %s"
- message << " (%.1fms)"
- info(message % [event.payload[:path], event.duration])
+ info("Sent file #{event.payload[:path]} (#{format_duration(event.duration)})")
end
def redirect_to(event)
info "Redirected to #{event.payload[:location]}"
end
def send_data(event)
- info("Sent data %s (%.1fms)" % [event.payload[:filename], event.duration])
+ info("Sent data #{event.payload[:filename]} (#{format_duration(event.duration)})")
end
%w(write_fragment read_fragment exist_fragment?
@@ -53,7 +51,8 @@ def send_data(event)
def #{method}(event)
key_or_path = event.payload[:key] || event.payload[:path]
human_name = #{method.to_s.humanize.inspect}
- info("\#{human_name} \#{key_or_path} \#{"(%.1fms)" % event.duration}")
+ duration = format_duration(event.duration)
+ info("\#{human_name} \#{key_or_path} \#{duration}")
end
METHOD
end
@@ -228,13 +228,13 @@ def session_options=(options)
# Override Rack's GET method to support indifferent access
def GET
- @env["action_dispatch.request.query_parameters"] ||= (normalize_parameters(super) || {})
+ @env["action_dispatch.request.query_parameters"] ||= deep_munge(normalize_parameters(super) || {})
end
alias :query_parameters :GET
# Override Rack's POST method to support indifferent access
def POST
- @env["action_dispatch.request.request_parameters"] ||= (normalize_parameters(super) || {})
+ @env["action_dispatch.request.request_parameters"] ||= deep_munge(normalize_parameters(super) || {})
end
alias :request_parameters :POST
@@ -49,7 +49,7 @@ def calculate_ip
forwarded_ips = ips_from('HTTP_X_FORWARDED_FOR')
remote_addrs = ips_from('REMOTE_ADDR')
- check_ip = client_ip && @middleware.check_ip
+ check_ip = client_ip && forwarded_ips.present? && @middleware.check_ip
if check_ip && !forwarded_ips.include?(client_ip)
# We don't know which came from the proxy, and which from the user
raise IpSpoofAttackError, "IP spoofing attack?!" \
@@ -611,9 +611,10 @@ def call(env)
def recognize_path(path, environment = {})
method = (environment[:method] || "GET").to_s.upcase
path = Journey::Router::Utils.normalize_path(path) unless path =~ %r{://}
+ extras = environment[:extras] || {}
begin
- env = Rack::MockRequest.env_for(path, {:method => method})
+ env = Rack::MockRequest.env_for(path, {:method => method, :params => extras})
rescue URI::InvalidURIError => e
raise ActionController::RoutingError, e.message
end
@@ -62,7 +62,7 @@ def assert_redirected_to(options = {}, message=nil)
redirect_expected = normalize_argument_to_redirection(options)
if redirect_is != redirect_expected
- flunk "Expected response to be a redirect to <#{redirect_expected}> but was a redirect to <#{redirect_is}>"
+ flunk(build_message(message, "Expected response to be a redirect to <?> but was a redirect to <?>", redirect_expected, redirect_is))
end
end
@@ -39,7 +39,7 @@ module RoutingAssertions
# # Test a custom route
# assert_recognizes({:controller => 'items', :action => 'show', :id => '1'}, 'view/item1')
def assert_recognizes(expected_options, path, extras={}, message=nil)
- request = recognized_request_for(path)
+ request = recognized_request_for(path, extras)
expected_options = expected_options.clone
extras.each_key { |key| expected_options.delete key } unless extras.nil?
@@ -179,7 +179,7 @@ def method_missing(selector, *args, &block)
private
# Recognizes the route for a given path.
- def recognized_request_for(path)
+ def recognized_request_for(path, extras = {})
if path.is_a?(Hash)
method = path[:method]
path = path[:path]
@@ -207,7 +207,7 @@ def recognized_request_for(path)
request.request_method = method if method
- params = @routes.recognize_path(path, { :method => method })
+ params = @routes.recognize_path(path, { :method => method, :extras => extras })
request.path_parameters = params.with_indifferent_access
request
@@ -2,7 +2,7 @@ module ActionPack
module VERSION #:nodoc:
MAJOR = 3
MINOR = 2
- TINY = 13
+ TINY = 18
PRE = nil
STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
@@ -138,12 +138,18 @@ def number_to_currency(number, options = {})
options.symbolize_keys!
+ options[:delimiter] = ERB::Util.html_escape(options[:delimiter]) if options[:delimiter]
+ options[:separator] = ERB::Util.html_escape(options[:separator]) if options[:separator]
+ options[:format] = ERB::Util.html_escape(options[:format]) if options[:format]
+ options[:negative_format] = ERB::Util.html_escape(options[:negative_format]) if options[:negative_format]
+
defaults = I18n.translate(:'number.format', :locale => options[:locale], :default => {})
currency = I18n.translate(:'number.currency.format', :locale => options[:locale], :default => {})
currency[:negative_format] ||= "-" + currency[:format] if currency[:format]
defaults = DEFAULT_CURRENCY_VALUES.merge(defaults).merge!(currency)
defaults[:negative_format] = "-" + options[:format] if options[:format]
+
options = defaults.merge!(options)
unit = options.delete(:unit)
@@ -156,7 +162,7 @@ def number_to_currency(number, options = {})
begin
value = number_with_precision(number, options.merge(:raise => true))
- format.gsub(/%n/, value).gsub(/%u/, unit).html_safe
+ format.gsub(/%n/, ERB::Util.html_escape(value)).gsub(/%u/, ERB::Util.html_escape(unit)).html_safe
rescue InvalidNumberError => e
if options[:raise]
raise
@@ -206,6 +212,9 @@ def number_to_percentage(number, options = {})
options.symbolize_keys!
+ options[:delimiter] = ERB::Util.html_escape(options[:delimiter]) if options[:delimiter]
+ options[:separator] = ERB::Util.html_escape(options[:separator]) if options[:separator]
+
defaults = I18n.translate(:'number.format', :locale => options[:locale], :default => {})
percentage = I18n.translate(:'number.percentage.format', :locale => options[:locale], :default => {})
defaults = defaults.merge(percentage)
@@ -255,6 +264,9 @@ def number_to_percentage(number, options = {})
def number_with_delimiter(number, options = {})
options.symbolize_keys!
+ options[:delimiter] = ERB::Util.html_escape(options[:delimiter]) if options[:delimiter]
+ options[:separator] = ERB::Util.html_escape(options[:separator]) if options[:separator]
+
begin
Float(number)
rescue ArgumentError, TypeError
@@ -578,7 +590,7 @@ def number_to_human(number, options = {})
units = options.delete :units
unit_exponents = case units
when Hash
- units
+ units = Hash[units.map { |k, v| [k, ERB::Util.html_escape(v)] }]
when String, Symbol
I18n.translate(:"#{units}", :locale => options[:locale], :raise => true)
when nil
Oops, something went wrong.

0 comments on commit cec1ae5

Please sign in to comment.