aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--RAILS_VERSION2
-rw-r--r--actionmailer/CHANGELOG.md7
-rw-r--r--actionmailer/lib/action_mailer/version.rb2
-rw-r--r--actionpack/CHANGELOG.md27
-rw-r--r--actionpack/actionpack.gemspec2
-rw-r--r--actionpack/lib/action_dispatch/http/request.rb10
-rw-r--r--actionpack/lib/action_dispatch/middleware/params_parser.rb4
-rw-r--r--actionpack/lib/action_dispatch/middleware/session/abstract_store.rb2
-rw-r--r--actionpack/lib/action_dispatch/middleware/session/cookie_store.rb11
-rw-r--r--actionpack/lib/action_dispatch/middleware/static.rb2
-rw-r--r--actionpack/lib/action_pack/version.rb2
-rw-r--r--actionpack/lib/action_view/helpers/form_helper.rb14
-rw-r--r--actionpack/lib/sprockets/helpers/rails_helper.rb4
-rw-r--r--actionpack/test/controller/render_test.rb3
-rw-r--r--actionpack/test/controller/webservice_test.rb13
-rw-r--r--actionpack/test/dispatch/request/json_params_parsing_test.rb15
-rw-r--r--actionpack/test/dispatch/request/xml_params_parsing_test.rb17
-rw-r--r--actionpack/test/fixtures/sprockets/app/javascripts/extra.js1
-rw-r--r--actionpack/test/fixtures/sprockets/app/stylesheets/extra.css1
-rw-r--r--actionpack/test/template/form_helper_test.rb14
-rw-r--r--actionpack/test/template/sprockets_helper_test.rb5
-rw-r--r--activemodel/CHANGELOG.md7
-rw-r--r--activemodel/lib/active_model/version.rb2
-rw-r--r--activerecord/CHANGELOG.md13
-rw-r--r--activerecord/lib/active_record/attribute_methods/write.rb9
-rw-r--r--activerecord/lib/active_record/connection_adapters/column.rb6
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb2
-rw-r--r--activerecord/lib/active_record/log_subscriber.rb6
-rw-r--r--activerecord/lib/active_record/relation/predicate_builder.rb7
-rw-r--r--activerecord/lib/active_record/scoping/named.rb4
-rw-r--r--activerecord/lib/active_record/version.rb2
-rw-r--r--activerecord/test/cases/associations/eager_test.rb1
-rw-r--r--activerecord/test/cases/column_test.rb8
-rw-r--r--activerecord/test/cases/log_subscriber_test.rb34
-rw-r--r--activerecord/test/cases/persistence_test.rb3
-rw-r--r--activerecord/test/cases/relation/where_test.rb16
-rw-r--r--activeresource/CHANGELOG.md8
-rw-r--r--activeresource/lib/active_resource/version.rb2
-rw-r--r--activeresource/test/abstract_unit.rb14
-rw-r--r--activeresource/test/cases/base_test.rb13
-rw-r--r--activesupport/CHANGELOG.md13
-rw-r--r--activesupport/lib/active_support/core_ext/hash/conversions.rb32
-rw-r--r--activesupport/lib/active_support/core_ext/time/calculations.rb12
-rw-r--r--activesupport/lib/active_support/time_with_zone.rb16
-rw-r--r--activesupport/lib/active_support/version.rb2
-rw-r--r--activesupport/test/core_ext/date_ext_test.rb4
-rw-r--r--activesupport/test/core_ext/hash_ext_test.rb28
-rw-r--r--activesupport/test/core_ext/time_ext_test.rb68
-rw-r--r--activesupport/test/core_ext/time_with_zone_test.rb10
-rw-r--r--railties/CHANGELOG.md8
-rw-r--r--railties/lib/rails/version.rb2
-rw-r--r--version.rb2
52 files changed, 343 insertions, 169 deletions
diff --git a/RAILS_VERSION b/RAILS_VERSION
index f15386a5d5..17ce91803c 100644
--- a/RAILS_VERSION
+++ b/RAILS_VERSION
@@ -1 +1 @@
-3.2.10
+3.2.11
diff --git a/actionmailer/CHANGELOG.md b/actionmailer/CHANGELOG.md
index b35c1da69f..fec3a5c423 100644
--- a/actionmailer/CHANGELOG.md
+++ b/actionmailer/CHANGELOG.md
@@ -1,4 +1,9 @@
-## Rails 3.2.11 (unreleased) ##
+## Rails 3.2.12 (unreleased) ##
+
+
+## Rails 3.2.11 (Jan 8, 2013) ##
+
+* No changes.
## Rails 3.2.10 (Jan 2, 2013) ##
diff --git a/actionmailer/lib/action_mailer/version.rb b/actionmailer/lib/action_mailer/version.rb
index 87ebf63169..695ea004f7 100644
--- a/actionmailer/lib/action_mailer/version.rb
+++ b/actionmailer/lib/action_mailer/version.rb
@@ -2,7 +2,7 @@ module ActionMailer
module VERSION #:nodoc:
MAJOR = 3
MINOR = 2
- TINY = 10
+ TINY = 11
PRE = nil
STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
diff --git a/actionpack/CHANGELOG.md b/actionpack/CHANGELOG.md
index d5befc0419..faa33f2992 100644
--- a/actionpack/CHANGELOG.md
+++ b/actionpack/CHANGELOG.md
@@ -1,4 +1,10 @@
-## Rails 3.2.11 (unreleased) ##
+## Rails 3.2.12 (unreleased) ##
+
+* Bump `rack` dependency to 1.4.3, eliminate `Rack::File` headers deprecation warning.
+
+ *Sam Ruby + Carlos Antonio da Silva*
+
+* Do not append second slash to `root_url` when using `trailing_slash: true`
* Prevent unnecessary asset compilation when using javascript_include_tag on
files with non-standard extensions.
@@ -6,6 +12,7 @@
*Noah Silas*
* Do not append second slash to root_url when using `trailing_slash: true`
+
Fix #8700.
Backport #8701.
@@ -18,6 +25,10 @@
*Yves Senn*
+* Fixes issue where duplicate assets can be required with sprockets.
+
+ *Jeremy Jackson*
+
* Fix a bug in `content_tag_for` that prevents it for work without a block.
*Jasl*
@@ -28,7 +39,7 @@
*Andrew White*
-* Fix a bug in ActionDispatch::Request#raw_post that caused env['rack.input']
+* Fix a bug in `ActionDispatch::Request#raw_post` that caused `env['rack.input']`
to be read but not rewound.
*Matt Venables*
@@ -38,14 +49,13 @@
#8376
render :partial => 'partial', :layout => true
-
# results in ActionView::MissingTemplate: Missing partial /true
*Yves Senn*
-* Accept symbols as #send_data :disposition value. [Backport #8329] *Elia Schito*
+* Accept symbols as `#send_data` :disposition value. [Backport #8329] *Elia Schito*
-* Add i18n scope to distance_of_time_in_words. [Backport #7997] *Steve Klabnik*
+* Add i18n scope to `distance_of_time_in_words`. [Backport #7997] *Steve Klabnik*
* Fix side effect of `url_for` changing the `:controller` string option. [Backport #6003]
Before:
@@ -59,7 +69,7 @@
puts controller #=> '/projects'
- [Nikita Beloglazov + Andrew White]
+ *Nikita Beloglazov + Andrew White*
* Introduce `ActionView::Template::Handlers::ERB.escape_whitelist`. This is a list
of mime types where template text is not html escaped by default. It prevents `Jack & Joe`
@@ -95,6 +105,11 @@
*Daniel Fox, Grant Hutchins & Trace Wax*
+## Rails 3.2.11 (Jan 8, 2013) ##
+
+* Strip nils from collections on JSON and XML posts. [CVE-2013-0155]
+
+
## Rails 3.2.10 (Jan 2, 2013) ##
* No changes.
diff --git a/actionpack/actionpack.gemspec b/actionpack/actionpack.gemspec
index ebd3c926eb..86e307255d 100644
--- a/actionpack/actionpack.gemspec
+++ b/actionpack/actionpack.gemspec
@@ -20,7 +20,7 @@ Gem::Specification.new do |s|
s.add_dependency('activemodel', version)
s.add_dependency('rack-cache', '~> 1.2')
s.add_dependency('builder', '~> 3.0.0')
- s.add_dependency('rack', '~> 1.4.0')
+ s.add_dependency('rack', '~> 1.4.3')
s.add_dependency('rack-test', '~> 0.6.1')
s.add_dependency('journey', '~> 1.0.4')
s.add_dependency('sprockets', '~> 2.2.1')
diff --git a/actionpack/lib/action_dispatch/http/request.rb b/actionpack/lib/action_dispatch/http/request.rb
index 0413346d94..2fac9668c1 100644
--- a/actionpack/lib/action_dispatch/http/request.rb
+++ b/actionpack/lib/action_dispatch/http/request.rb
@@ -248,18 +248,14 @@ module ActionDispatch
LOCALHOST.any? { |local_ip| local_ip === remote_addr && local_ip === remote_ip }
end
- protected
-
# Remove nils from the params hash
def deep_munge(hash)
- keys = hash.keys.find_all { |k| hash[k] == [nil] }
- keys.each { |k| hash[k] = nil }
-
- hash.each_value do |v|
+ hash.each do |k, v|
case v
when Array
v.grep(Hash) { |x| deep_munge(x) }
v.compact!
+ hash[k] = nil if v.empty?
when Hash
deep_munge(v)
end
@@ -268,6 +264,8 @@ module ActionDispatch
hash
end
+ protected
+
def parse_query(qs)
deep_munge(super)
end
diff --git a/actionpack/lib/action_dispatch/middleware/params_parser.rb b/actionpack/lib/action_dispatch/middleware/params_parser.rb
index 6ded9dbfed..ac726895fa 100644
--- a/actionpack/lib/action_dispatch/middleware/params_parser.rb
+++ b/actionpack/lib/action_dispatch/middleware/params_parser.rb
@@ -38,13 +38,13 @@ module ActionDispatch
when Proc
strategy.call(request.raw_post)
when :xml_simple, :xml_node
- data = Hash.from_xml(request.body.read) || {}
+ data = request.deep_munge(Hash.from_xml(request.body.read) || {})
request.body.rewind if request.body.respond_to?(:rewind)
data.with_indifferent_access
when :yaml
YAML.load(request.raw_post)
when :json
- data = ActiveSupport::JSON.decode(request.body)
+ data = request.deep_munge ActiveSupport::JSON.decode(request.body)
request.body.rewind if request.body.respond_to?(:rewind)
data = {:_json => data} unless data.is_a?(Hash)
data.with_indifferent_access
diff --git a/actionpack/lib/action_dispatch/middleware/session/abstract_store.rb b/actionpack/lib/action_dispatch/middleware/session/abstract_store.rb
index c04fee21dc..cb6d98f09a 100644
--- a/actionpack/lib/action_dispatch/middleware/session/abstract_store.rb
+++ b/actionpack/lib/action_dispatch/middleware/session/abstract_store.rb
@@ -25,6 +25,8 @@ module ActionDispatch
module Compatibility
def initialize(app, options = {})
options[:key] ||= '_session_id'
+ # FIXME Rack's secret is not being used
+ options[:secret] ||= SecureRandom.hex(30)
super
end
diff --git a/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb b/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb
index 29e9e6c261..80c596fd51 100644
--- a/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb
+++ b/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb
@@ -22,15 +22,12 @@ module ActionDispatch
#
# Session options:
#
- # * <tt>:secret</tt>: An application-wide key string or block returning a
- # string called per generated digest. The block is called with the
- # CGI::Session instance as an argument. It's important that the secret
- # is not vulnerable to a dictionary attack. Therefore, you should choose
- # a secret consisting of random numbers and letters and more than 30
- # characters. Examples:
+ # * <tt>:secret</tt>: An application-wide key string. It's important that
+ # the secret is not vulnerable to a dictionary attack. Therefore, you
+ # should choose a secret consisting of random numbers and letters and
+ # more than 30 characters.
#
# :secret => '449fe2e7daee471bffae2fd8dc02313d'
- # :secret => Proc.new { User.current_user.secret_key }
#
# * <tt>:digest</tt>: The message digest algorithm used to verify session
# integrity defaults to 'SHA1' but may be any digest provided by OpenSSL,
diff --git a/actionpack/lib/action_dispatch/middleware/static.rb b/actionpack/lib/action_dispatch/middleware/static.rb
index ad11b6a211..6e81073e1e 100644
--- a/actionpack/lib/action_dispatch/middleware/static.rb
+++ b/actionpack/lib/action_dispatch/middleware/static.rb
@@ -5,7 +5,7 @@ module ActionDispatch
def initialize(root, cache_control)
@root = root.chomp('/')
@compiled_root = /^#{Regexp.escape(root)}/
- @file_server = ::Rack::File.new(@root, cache_control)
+ @file_server = ::Rack::File.new(@root, 'Cache-Control' => cache_control)
end
def match?(path)
diff --git a/actionpack/lib/action_pack/version.rb b/actionpack/lib/action_pack/version.rb
index ad2546a13d..10832373e1 100644
--- a/actionpack/lib/action_pack/version.rb
+++ b/actionpack/lib/action_pack/version.rb
@@ -2,7 +2,7 @@ module ActionPack
module VERSION #:nodoc:
MAJOR = 3
MINOR = 2
- TINY = 10
+ TINY = 11
PRE = nil
STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb
index d00bad7608..7df74d96fb 100644
--- a/actionpack/lib/action_view/helpers/form_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_helper.rb
@@ -331,9 +331,9 @@ module ActionView
# In many cases you will want to wrap the above in another helper, so you
# could do something like the following:
#
- # def labelled_form_for(record_or_name_or_array, *args, &proc)
+ # def labelled_form_for(record_or_name_or_array, *args, &block)
# options = args.extract_options!
- # form_for(record_or_name_or_array, *(args << options.merge(:builder => LabellingFormBuilder)), &proc)
+ # form_for(record_or_name_or_array, *(args << options.merge(:builder => LabellingFormBuilder)), &block)
# end
#
# If you don't need to attach a form to a model instance, then check out
@@ -355,7 +355,7 @@ module ActionView
# <%= form_for @invoice, :url => external_url, :authenticity_token => false do |f|
# ...
# <% end %>
- def form_for(record, options = {}, &proc)
+ def form_for(record, options = {}, &block)
raise ArgumentError, "Missing block" unless block_given?
options[:html] ||= {}
@@ -374,12 +374,10 @@ module ActionView
options[:html][:method] = options.delete(:method) if options.has_key?(:method)
options[:html][:authenticity_token] = options.delete(:authenticity_token)
- builder = options[:parent_builder] = instantiate_builder(object_name, object, options, &proc)
- fields_for = fields_for(object_name, object, options, &proc)
+ builder = options[:parent_builder] = instantiate_builder(object_name, object, options, &block)
+ output = capture(builder, &block)
default_options = builder.multipart? ? { :multipart => true } : {}
- output = form_tag(options.delete(:url) || {}, default_options.merge!(options.delete(:html)))
- output << fields_for
- output.safe_concat('</form>')
+ form_tag(options.delete(:url) || {}, default_options.merge!(options.delete(:html))) { output }
end
def apply_form_for_options!(object_or_array, options) #:nodoc:
diff --git a/actionpack/lib/sprockets/helpers/rails_helper.rb b/actionpack/lib/sprockets/helpers/rails_helper.rb
index a1e504be25..51f0cbb2da 100644
--- a/actionpack/lib/sprockets/helpers/rails_helper.rb
+++ b/actionpack/lib/sprockets/helpers/rails_helper.rb
@@ -31,7 +31,7 @@ module Sprockets
else
super(source.to_s, { :src => path_to_asset(source, :ext => 'js', :body => body, :digest => digest) }.merge!(options))
end
- end.uniq.join("\n").html_safe
+ end.flatten.uniq.join("\n").html_safe
end
def stylesheet_link_tag(*sources)
@@ -48,7 +48,7 @@ module Sprockets
else
super(source.to_s, { :href => path_to_asset(source, :ext => 'css', :body => body, :protocol => :request, :digest => digest) }.merge!(options))
end
- end.uniq.join("\n").html_safe
+ end.flatten.uniq.join("\n").html_safe
end
def asset_path(source, options = {})
diff --git a/actionpack/test/controller/render_test.rb b/actionpack/test/controller/render_test.rb
index 8c631e218f..3964540def 100644
--- a/actionpack/test/controller/render_test.rb
+++ b/actionpack/test/controller/render_test.rb
@@ -1406,10 +1406,11 @@ class RenderTest < ActionController::TestCase
end
def test_locals_option_to_assert_template_is_not_supported
+ get :partial_collection_with_locals
+
warning_buffer = StringIO.new
$stderr = warning_buffer
- get :partial_collection_with_locals
assert_template :partial => 'customer_greeting', :locals => { :greeting => 'Bonjour' }
assert_equal "the :locals option to #assert_template is only supported in a ActionView::TestCase\n", warning_buffer.string
ensure
diff --git a/actionpack/test/controller/webservice_test.rb b/actionpack/test/controller/webservice_test.rb
index ae8588cbb0..13b6f4fc39 100644
--- a/actionpack/test/controller/webservice_test.rb
+++ b/actionpack/test/controller/webservice_test.rb
@@ -118,6 +118,19 @@ class WebServiceTest < ActionDispatch::IntegrationTest
end
end
+ def test_post_xml_using_a_disallowed_type_attribute
+ $stderr = StringIO.new
+ with_test_route_set do
+ post '/', '<foo type="symbol">value</foo>', 'CONTENT_TYPE' => 'application/xml'
+ assert_response 500
+
+ post '/', '<foo type="yaml">value</foo>', 'CONTENT_TYPE' => 'application/xml'
+ assert_response 500
+ end
+ ensure
+ $stderr = STDERR
+ end
+
def test_register_and_use_yaml
with_test_route_set do
with_params_parsers Mime::YAML => Proc.new { |d| YAML.load(d) } do
diff --git a/actionpack/test/dispatch/request/json_params_parsing_test.rb b/actionpack/test/dispatch/request/json_params_parsing_test.rb
index ad44b4b16a..fbf2ce1fbe 100644
--- a/actionpack/test/dispatch/request/json_params_parsing_test.rb
+++ b/actionpack/test/dispatch/request/json_params_parsing_test.rb
@@ -30,6 +30,21 @@ class JsonParamsParsingTest < ActionDispatch::IntegrationTest
)
end
+ test "nils are stripped from collections" do
+ assert_parses(
+ {"person" => nil},
+ "{\"person\":[null]}", { 'CONTENT_TYPE' => 'application/json' }
+ )
+ assert_parses(
+ {"person" => ['foo']},
+ "{\"person\":[\"foo\",null]}", { 'CONTENT_TYPE' => 'application/json' }
+ )
+ assert_parses(
+ {"person" => nil},
+ "{\"person\":[null, null]}", { 'CONTENT_TYPE' => 'application/json' }
+ )
+ end
+
test "logs error if parsing unsuccessful" do
with_test_routing do
output = StringIO.new
diff --git a/actionpack/test/dispatch/request/xml_params_parsing_test.rb b/actionpack/test/dispatch/request/xml_params_parsing_test.rb
index 0984f00066..cadafa7f38 100644
--- a/actionpack/test/dispatch/request/xml_params_parsing_test.rb
+++ b/actionpack/test/dispatch/request/xml_params_parsing_test.rb
@@ -30,6 +30,23 @@ class XmlParamsParsingTest < ActionDispatch::IntegrationTest
assert_equal "<ok>bar</ok>", resp.body
end
+ def assert_parses(expected, xml)
+ with_test_routing do
+ post "/parse", xml, default_headers
+ assert_response :ok
+ assert_equal(expected, TestController.last_request_parameters)
+ end
+ end
+
+ test "nils are stripped from collections" do
+ assert_parses(
+ {"hash" => { "person" => nil} },
+ "<hash><person type=\"array\"><person nil=\"true\"/></person></hash>")
+ assert_parses(
+ {"hash" => { "person" => ['foo']} },
+ "<hash><person type=\"array\"><person>foo</person><person nil=\"true\"/></person>\n</hash>")
+ end
+
test "parses hash params" do
with_test_routing do
xml = "<person><name>David</name></person>"
diff --git a/actionpack/test/fixtures/sprockets/app/javascripts/extra.js b/actionpack/test/fixtures/sprockets/app/javascripts/extra.js
index e69de29bb2..e611d2b129 100644
--- a/actionpack/test/fixtures/sprockets/app/javascripts/extra.js
+++ b/actionpack/test/fixtures/sprockets/app/javascripts/extra.js
@@ -0,0 +1 @@
+//= require xmlhr
diff --git a/actionpack/test/fixtures/sprockets/app/stylesheets/extra.css b/actionpack/test/fixtures/sprockets/app/stylesheets/extra.css
index e69de29bb2..2365eaa4cd 100644
--- a/actionpack/test/fixtures/sprockets/app/stylesheets/extra.css
+++ b/actionpack/test/fixtures/sprockets/app/stylesheets/extra.css
@@ -0,0 +1 @@
+/*= require style */
diff --git a/actionpack/test/template/form_helper_test.rb b/actionpack/test/template/form_helper_test.rb
index 49a325af79..7b35424ec7 100644
--- a/actionpack/test/template/form_helper_test.rb
+++ b/actionpack/test/template/form_helper_test.rb
@@ -755,7 +755,6 @@ class FormHelperTest < ActionView::TestCase
assert_dom_equal expected, output_buffer
end
-
def test_form_for_with_format
form_for(@post, :format => :json, :html => { :id => "edit_post_123", :class => "edit_post" }) do |f|
concat f.label(:title)
@@ -2217,6 +2216,19 @@ class FormHelperTest < ActionView::TestCase
assert_equal "fields", output
end
+ def test_form_for_only_instantiates_builder_once
+ initialization_count = 0
+ builder_class = Class.new(ActionView::Helpers::FormBuilder) do
+ define_method :initialize do |*args|
+ super(*args)
+ initialization_count += 1
+ end
+ end
+
+ form_for(@post, :builder => builder_class) { }
+ assert_equal 1, initialization_count, 'form builder instantiated more than once'
+ end
+
protected
def protect_against_forgery?
false
diff --git a/actionpack/test/template/sprockets_helper_test.rb b/actionpack/test/template/sprockets_helper_test.rb
index 07ebd18f99..93832c7bd9 100644
--- a/actionpack/test/template/sprockets_helper_test.rb
+++ b/actionpack/test/template/sprockets_helper_test.rb
@@ -266,6 +266,8 @@ class SprocketsHelperTest < ActionView::TestCase
javascript_include_tag('/javascripts/application')
assert_match %r{<script src="/assets/xmlhr-[0-9a-f]+.js\?body=1" type="text/javascript"></script>\n<script src="/assets/application-[0-9a-f]+.js\?body=1" type="text/javascript"></script>},
javascript_include_tag(:application)
+ assert_match %r{<script src="/assets/xmlhr-[0-9a-f]+.js\?body=1" type="text/javascript"></script>\n<script src="/assets/application-[0-9a-f]+.js\?body=1" type="text/javascript"></script>\n<script src="/assets/extra-[0-9a-f]+.js\?body=1" type="text/javascript"></script>},
+ javascript_include_tag(:application, :extra)
end
test "precompiled assets with an extension when no JS runtime is available" do
@@ -331,6 +333,9 @@ class SprocketsHelperTest < ActionView::TestCase
assert_match %r{<link href="/assets/style-[0-9a-f]+.css\?body=1" media="screen" rel="stylesheet" type="text/css" />\n<link href="/assets/application-[0-9a-f]+.css\?body=1" media="screen" rel="stylesheet" type="text/css" />},
stylesheet_link_tag(:application)
+ assert_match %r{<link href="/assets/style-[0-9a-f]+.css\?body=1" media="screen" rel="stylesheet" type="text/css" />\n<link href="/assets/application-[0-9a-f]+.css\?body=1" media="screen" rel="stylesheet" type="text/css" />\n<link href="/assets/extra-[0-9a-f]+.css\?body=1" media="screen" rel="stylesheet" type="text/css" />},
+ stylesheet_link_tag(:application, :extra)
+
assert_match %r{<link href="/assets/style-[0-9a-f]+.css\?body=1" media="print" rel="stylesheet" type="text/css" />\n<link href="/assets/application-[0-9a-f]+.css\?body=1" media="print" rel="stylesheet" type="text/css" />},
stylesheet_link_tag(:application, :media => "print")
end
diff --git a/activemodel/CHANGELOG.md b/activemodel/CHANGELOG.md
index b56016b020..fe83324848 100644
--- a/activemodel/CHANGELOG.md
+++ b/activemodel/CHANGELOG.md
@@ -1,8 +1,13 @@
-## Rails 3.2.11 (unreleased) ##
+## Rails 3.2.12 (unreleased) ##
* Specify type of singular association during serialization *Steve Klabnik*
+## Rails 3.2.11 (Jan 8, 2013) ##
+
+* No changes.
+
+
## Rails 3.2.10 (Jan 2, 2013) ##
* No changes.
diff --git a/activemodel/lib/active_model/version.rb b/activemodel/lib/active_model/version.rb
index 1064e9ac22..51a678d151 100644
--- a/activemodel/lib/active_model/version.rb
+++ b/activemodel/lib/active_model/version.rb
@@ -2,7 +2,7 @@ module ActiveModel
module VERSION #:nodoc:
MAJOR = 3
MINOR = 2
- TINY = 10
+ TINY = 11
PRE = nil
STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md
index 1606b1a9f6..ec5fd2785a 100644
--- a/activerecord/CHANGELOG.md
+++ b/activerecord/CHANGELOG.md
@@ -1,9 +1,10 @@
-## Rails 3.2.11 (unreleased)
+## Rails 3.2.12 (unreleased) ##
-* Fix undefined method `to_i` when calling `new` on a scope that uses an Array.
- Fixes #8718.
+* Fix undefined method `to_i` when calling `new` on a scope that uses an
+ Array; Fix FloatDomainError when setting integer column to NaN.
+ Fixes #8718, #8734, #8757.
- *Jason Stirk*
+ *Jason Stirk + Tristan Harward*
* Serialized attributes can be serialized in integer columns.
Fix #8575.
@@ -178,6 +179,10 @@
*Gabriel Sobrinho, Ricardo Henrique*
+## Rails 3.2.11 (Jan 8, 2013) ##
+
+* Fix querying with an empty hash *Damien Mathieu* [CVE-2013-0155]
+
## Rails 3.2.10 (Jan 2, 2013) ##
diff --git a/activerecord/lib/active_record/attribute_methods/write.rb b/activerecord/lib/active_record/attribute_methods/write.rb
index 8c6fa90a28..16aed7348f 100644
--- a/activerecord/lib/active_record/attribute_methods/write.rb
+++ b/activerecord/lib/active_record/attribute_methods/write.rb
@@ -54,12 +54,13 @@ module ActiveRecord
end
def convert_number_column_value(value)
- if value == false
+ case value
+ when FalseClass
0
- elsif value == true
+ when TrueClass
1
- elsif value.is_a?(String) && value.blank?
- nil
+ when String
+ value.presence
else
value
end
diff --git a/activerecord/lib/active_record/connection_adapters/column.rb b/activerecord/lib/active_record/connection_adapters/column.rb
index b93a728a39..e22d9f7222 100644
--- a/activerecord/lib/active_record/connection_adapters/column.rb
+++ b/activerecord/lib/active_record/connection_adapters/column.rb
@@ -175,11 +175,7 @@ module ActiveRecord
when TrueClass, FalseClass
value ? 1 : 0
else
- if value.respond_to?(:to_i)
- value.to_i
- else
- nil
- end
+ value.to_i rescue nil
end
end
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
index 5a53135901..8806693397 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
@@ -315,8 +315,6 @@ module ActiveRecord
@visitor = BindSubstitution.new self
end
- connection_parameters.delete :prepared_statements
-
@connection_parameters, @config = connection_parameters, config
# @local_tz is initialized as nil to avoid warnings when connect tries to use it
diff --git a/activerecord/lib/active_record/log_subscriber.rb b/activerecord/lib/active_record/log_subscriber.rb
index a25f2c7bca..2b6488f183 100644
--- a/activerecord/lib/active_record/log_subscriber.rb
+++ b/activerecord/lib/active_record/log_subscriber.rb
@@ -32,7 +32,11 @@ module ActiveRecord
unless (payload[:binds] || []).empty?
binds = " " + payload[:binds].map { |col,v|
- [col.name, v]
+ if col
+ [col.name, v]
+ else
+ [nil, v]
+ end
}.inspect
end
diff --git a/activerecord/lib/active_record/relation/predicate_builder.rb b/activerecord/lib/active_record/relation/predicate_builder.rb
index 6b118b4912..b31fdfd981 100644
--- a/activerecord/lib/active_record/relation/predicate_builder.rb
+++ b/activerecord/lib/active_record/relation/predicate_builder.rb
@@ -6,7 +6,12 @@ module ActiveRecord
if allow_table_name && value.is_a?(Hash)
table = Arel::Table.new(column, engine)
- build_from_hash(engine, value, table, false)
+
+ if value.empty?
+ '1 = 2'
+ else
+ build_from_hash(engine, value, table, false)
+ end
else
column = column.to_s
diff --git a/activerecord/lib/active_record/scoping/named.rb b/activerecord/lib/active_record/scoping/named.rb
index d6b0265fb3..767b30f51f 100644
--- a/activerecord/lib/active_record/scoping/named.rb
+++ b/activerecord/lib/active_record/scoping/named.rb
@@ -161,16 +161,14 @@ module ActiveRecord
# end
#
# def self.titles
- # map(&:title)
+ # pluck(:title)
# end
- #
# end
#
# We are able to call the methods like this:
#
# Article.published.featured.latest_article
# Article.featured.titles
-
def scope(name, scope_options = {})
name = name.to_sym
valid_scope_name?(name)
diff --git a/activerecord/lib/active_record/version.rb b/activerecord/lib/active_record/version.rb
index 36266e968b..ff9fa279f4 100644
--- a/activerecord/lib/active_record/version.rb
+++ b/activerecord/lib/active_record/version.rb
@@ -2,7 +2,7 @@ module ActiveRecord
module VERSION #:nodoc:
MAJOR = 3
MINOR = 2
- TINY = 10
+ TINY = 11
PRE = nil
STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
diff --git a/activerecord/test/cases/associations/eager_test.rb b/activerecord/test/cases/associations/eager_test.rb
index d3601e0dba..20c6b691fc 100644
--- a/activerecord/test/cases/associations/eager_test.rb
+++ b/activerecord/test/cases/associations/eager_test.rb
@@ -592,7 +592,6 @@ class EagerAssociationTest < ActiveRecord::TestCase
# gets raw row hashes from the database and then instantiates them, this test ensures that
# it only instantiates one actual object per record from the database.
def test_has_and_belongs_to_many_should_not_instantiate_same_records_multiple_times
- welcome = posts(:welcome)
categories = Category.includes(:posts)
general = categories.find { |c| c == categories(:general) }
diff --git a/activerecord/test/cases/column_test.rb b/activerecord/test/cases/column_test.rb
index 8017a49827..800cfbdef9 100644
--- a/activerecord/test/cases/column_test.rb
+++ b/activerecord/test/cases/column_test.rb
@@ -56,6 +56,14 @@ module ActiveRecord
column = Column.new("field", nil, "integer")
assert_nil column.type_cast(Object.new)
end
+
+ if RUBY_VERSION > '1.9'
+ def test_type_cast_nan_and_infinity_to_integer
+ column = Column.new("field", nil, "integer")
+ assert_nil column.type_cast(Float::NAN)
+ assert_nil column.type_cast(1.0/0.0)
+ end
+ end
end
end
end
diff --git a/activerecord/test/cases/log_subscriber_test.rb b/activerecord/test/cases/log_subscriber_test.rb
index e24a5ca5aa..10ee86de4a 100644
--- a/activerecord/test/cases/log_subscriber_test.rb
+++ b/activerecord/test/cases/log_subscriber_test.rb
@@ -7,6 +7,19 @@ class LogSubscriberTest < ActiveRecord::TestCase
include ActiveSupport::LogSubscriber::TestHelper
include ActiveSupport::BufferedLogger::Severity
+ class TestDebugLogSubscriber < ActiveRecord::LogSubscriber
+ attr_reader :debugs
+
+ def initialize
+ @debugs = []
+ super
+ end
+
+ def debug message
+ @debugs << message
+ end
+ end
+
fixtures :posts
def setup
@@ -32,18 +45,7 @@ class LogSubscriberTest < ActiveRecord::TestCase
def test_schema_statements_are_ignored
event = Struct.new(:duration, :payload)
- logger = Class.new(ActiveRecord::LogSubscriber) {
- attr_accessor :debugs
-
- def initialize
- @debugs = []
- super
- end
-
- def debug message
- @debugs << message
- end
- }.new
+ logger = TestDebugLogSubscriber.new
assert_equal 0, logger.debugs.length
logger.sql(event.new(0, { :sql => 'hi mom!' }))
@@ -56,6 +58,14 @@ class LogSubscriberTest < ActiveRecord::TestCase
assert_equal 2, logger.debugs.length
end
+ def test_ignore_binds_payload_with_nil_column
+ event = Struct.new(:duration, :payload)
+
+ logger = TestDebugLogSubscriber.new
+ logger.sql(event.new(0, :sql => 'hi mom!', :binds => [[nil, 1]]))
+ assert_equal 1, logger.debugs.length
+ end
+
def test_basic_query_logging
Developer.all
wait
diff --git a/activerecord/test/cases/persistence_test.rb b/activerecord/test/cases/persistence_test.rb
index 00dc1f6d72..db1ba3549f 100644
--- a/activerecord/test/cases/persistence_test.rb
+++ b/activerecord/test/cases/persistence_test.rb
@@ -394,7 +394,6 @@ class PersistencesTest < ActiveRecord::TestCase
def test_update_attribute_with_one_updated
t = Topic.first
- title = t.title
t.update_attribute(:title, 'super_title')
assert_equal 'super_title', t.title
assert !t.changed?, "topic should not have changed"
@@ -492,7 +491,7 @@ class PersistencesTest < ActiveRecord::TestCase
def test_update_column_with_one_changed_and_one_updated
t = Topic.order('id').limit(1).first
- title, author_name = t.title, t.author_name
+ author_name = t.author_name
t.author_name = 'John'
t.update_column(:title, 'super_title')
assert_equal 'John', t.author_name
diff --git a/activerecord/test/cases/relation/where_test.rb b/activerecord/test/cases/relation/where_test.rb
index b9eef1d32f..80158332f9 100644
--- a/activerecord/test/cases/relation/where_test.rb
+++ b/activerecord/test/cases/relation/where_test.rb
@@ -1,9 +1,11 @@
require "cases/helper"
require 'models/post'
+require 'models/comment'
+require 'models/edge'
module ActiveRecord
class WhereTest < ActiveRecord::TestCase
- fixtures :posts
+ fixtures :posts, :edges
def test_where_error
assert_raises(ActiveRecord::StatementInvalid) do
@@ -21,5 +23,17 @@ module ActiveRecord
post = Post.first
assert_equal post, Post.where(:posts => { 'id' => post.id }).first
end
+
+ def test_where_with_table_name_and_empty_hash
+ assert_equal 0, Post.where(:posts => {}).count
+ end
+
+ def test_where_with_table_name_and_empty_array
+ assert_equal 0, Post.where(:id => []).count
+ end
+
+ def test_where_with_empty_hash_and_no_foreign_key
+ assert_equal 0, Edge.where(:sink => {}).count
+ end
end
end
diff --git a/activeresource/CHANGELOG.md b/activeresource/CHANGELOG.md
index 176ffb4723..98a67b96a5 100644
--- a/activeresource/CHANGELOG.md
+++ b/activeresource/CHANGELOG.md
@@ -1,4 +1,10 @@
-## Rails 3.2.11 ##
+## Rails 3.2.12 (unreleased) ##
+
+
+## Rails 3.2.11 (Jan 8, 2013) ##
+
+* No changes.
+
## Rails 3.2.10 (Jan 2, 2013) ##
diff --git a/activeresource/lib/active_resource/version.rb b/activeresource/lib/active_resource/version.rb
index adbcaaa9c6..500da6c137 100644
--- a/activeresource/lib/active_resource/version.rb
+++ b/activeresource/lib/active_resource/version.rb
@@ -2,7 +2,7 @@ module ActiveResource
module VERSION #:nodoc:
MAJOR = 3
MINOR = 2
- TINY = 10
+ TINY = 11
PRE = nil
STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
diff --git a/activeresource/test/abstract_unit.rb b/activeresource/test/abstract_unit.rb
index 9c1e9a526d..583fd2afb7 100644
--- a/activeresource/test/abstract_unit.rb
+++ b/activeresource/test/abstract_unit.rb
@@ -77,19 +77,6 @@ def setup_response
}]
}
}.to_json
- # - resource with yaml array of strings; for ARs using serialize :bar, Array
- @marty = <<-eof.strip
- <?xml version=\"1.0\" encoding=\"UTF-8\"?>
- <person>
- <id type=\"integer\">5</id>
- <name>Marty</name>
- <colors type=\"yaml\">---
- - \"red\"
- - \"green\"
- - \"blue\"
- </colors>
- </person>
- eof
@startup_sound = {
:sound => {
@@ -101,7 +88,6 @@ def setup_response
mock.get "/people/1.json", {}, @matz
mock.get "/people/1.xml", {}, @matz_xml
mock.get "/people/2.xml", {}, @david
- mock.get "/people/5.xml", {}, @marty
mock.get "/people/Greg.json", {}, @greg
mock.get "/people/6.json", {}, @joe
mock.get "/people/4.json", { 'key' => 'value' }, nil, 404
diff --git a/activeresource/test/cases/base_test.rb b/activeresource/test/cases/base_test.rb
index 5ef8a51ef7..983f0541a8 100644
--- a/activeresource/test/cases/base_test.rb
+++ b/activeresource/test/cases/base_test.rb
@@ -1077,19 +1077,6 @@ class BaseTest < Test::Unit::TestCase
end
end
- def test_load_yaml_array
- assert_nothing_raised do
- Person.format = :xml
- marty = Person.find(5)
- assert_equal 3, marty.colors.size
- marty.colors.each do |color|
- assert_kind_of String, color
- end
- end
- ensure
- Person.format = :json
- end
-
def test_with_custom_formatter
addresses = [{ :id => "1", :street => "1 Infinite Loop", :city => "Cupertino", :state => "CA" }].to_xml(:root => :addresses)
diff --git a/activesupport/CHANGELOG.md b/activesupport/CHANGELOG.md
index 2278c04f0d..18ca36ab06 100644
--- a/activesupport/CHANGELOG.md
+++ b/activesupport/CHANGELOG.md
@@ -1,4 +1,4 @@
-## Rails 3.2.11 (unreleased)
+## Rails 3.2.12 (unreleased) ##
* Remove surrogate unicode character encoding from ActiveSupport::JSON.encode
The encoding scheme was broken for unicode characters outside the basic
@@ -20,11 +20,20 @@
*Daniele Sluijters*
+## Rails 3.2.11 (Jan 8, 2012) ##
+
+* Hash.from_xml raises when it encounters type="symbol" or type="yaml".
+ Use Hash.from_trusted_xml to parse this XML.
+
+ CVE-2013-0156
+
+ *Jeremy Kemper*
+
+
## Rails 3.2.10 (Jan 2, 2013) ##
* No changes.
-
## Rails 3.2.9 (Nov 12, 2012) ##
* Add logger.push_tags and .pop_tags to complement logger.tagged:
diff --git a/activesupport/lib/active_support/core_ext/hash/conversions.rb b/activesupport/lib/active_support/core_ext/hash/conversions.rb
index 5f07bb4f5a..b820a167a2 100644
--- a/activesupport/lib/active_support/core_ext/hash/conversions.rb
+++ b/activesupport/lib/active_support/core_ext/hash/conversions.rb
@@ -85,15 +85,33 @@ class Hash
end
end
+ class DisallowedType < StandardError #:nodoc:
+ def initialize(type)
+ super "Disallowed type attribute: #{type.inspect}"
+ end
+ end
+
+ DISALLOWED_XML_TYPES = %w(symbol yaml)
+
class << self
- def from_xml(xml)
- typecast_xml_value(unrename_keys(ActiveSupport::XmlMini.parse(xml)))
+ def from_xml(xml, disallowed_types = nil)
+ typecast_xml_value(unrename_keys(ActiveSupport::XmlMini.parse(xml)), disallowed_types)
+ end
+
+ def from_trusted_xml(xml)
+ from_xml xml, []
end
private
- def typecast_xml_value(value)
+ def typecast_xml_value(value, disallowed_types = nil)
+ disallowed_types ||= DISALLOWED_XML_TYPES
+
case value.class.to_s
when 'Hash'
+ if value.include?('type') && !value['type'].is_a?(Hash) && disallowed_types.include?(value['type'])
+ raise DisallowedType, value['type']
+ end
+
if value['type'] == 'array'
_, entries = Array.wrap(value.detect { |k,v| not v.is_a?(String) })
if entries.nil? || (c = value['__content__'] && c.blank?)
@@ -101,9 +119,9 @@ class Hash
else
case entries.class.to_s # something weird with classes not matching here. maybe singleton methods breaking is_a?
when "Array"
- entries.collect { |v| typecast_xml_value(v) }
+ entries.collect { |v| typecast_xml_value(v, disallowed_types) }
when "Hash"
- [typecast_xml_value(entries)]
+ [typecast_xml_value(entries, disallowed_types)]
else
raise "can't typecast #{entries.inspect}"
end
@@ -127,14 +145,14 @@ class Hash
elsif value['type'] && value.size == 1 && !value['type'].is_a?(::Hash)
nil
else
- xml_value = Hash[value.map { |k,v| [k, typecast_xml_value(v)] }]
+ xml_value = Hash[value.map { |k,v| [k, typecast_xml_value(v, disallowed_types)] }]
# Turn { :files => { :file => #<StringIO> } into { :files => #<StringIO> } so it is compatible with
# how multipart uploaded files from HTML appear
xml_value["file"].is_a?(StringIO) ? xml_value["file"] : xml_value
end
when 'Array'
- value.map! { |i| typecast_xml_value(i) }
+ value.map! { |i| typecast_xml_value(i, disallowed_types) }
value.length > 1 ? value : value.first
when 'String'
value
diff --git a/activesupport/lib/active_support/core_ext/time/calculations.rb b/activesupport/lib/active_support/core_ext/time/calculations.rb
index 34d4d88bd3..9146d82bd8 100644
--- a/activesupport/lib/active_support/core_ext/time/calculations.rb
+++ b/activesupport/lib/active_support/core_ext/time/calculations.rb
@@ -217,7 +217,7 @@ class Time
# Returns a new Time representing the end of the day, 23:59:59.999999 (.999999999 in ruby1.9)
def end_of_day
- change(:hour => 23, :min => 59, :sec => 59, :usec => 999999.999)
+ change(:hour => 23, :min => 59, :sec => 59, :usec => Rational(999999999, 1000))
end
# Returns a new Time representing the start of the hour (x:00)
@@ -228,11 +228,7 @@ class Time
# Returns a new Time representing the end of the hour, x:59:59.999999 (.999999999 in ruby1.9)
def end_of_hour
- change(
- :min => 59,
- :sec => 59,
- :usec => 999999.999
- )
+ change(:min => 59, :sec => 59, :usec => Rational(999999999, 1000))
end
# Returns a new Time representing the start of the month (1st of the month, 0:00)
@@ -246,7 +242,7 @@ class Time
def end_of_month
#self - ((self.mday-1).days + self.seconds_since_midnight)
last_day = ::Time.days_in_month(month, year)
- change(:day => last_day, :hour => 23, :min => 59, :sec => 59, :usec => 999999.999)
+ change(:day => last_day, :hour => 23, :min => 59, :sec => 59, :usec => Rational(999999999, 1000))
end
alias :at_end_of_month :end_of_month
@@ -270,7 +266,7 @@ class Time
# Returns a new Time representing the end of the year (end of the 31st of december)
def end_of_year
- change(:month => 12, :day => 31, :hour => 23, :min => 59, :sec => 59, :usec => 999999.999)
+ change(:month => 12, :day => 31, :hour => 23, :min => 59, :sec => 59, :usec => Rational(999999999, 1000))
end
alias :at_end_of_year :end_of_year
diff --git a/activesupport/lib/active_support/time_with_zone.rb b/activesupport/lib/active_support/time_with_zone.rb
index a3c378f057..f39b58a980 100644
--- a/activesupport/lib/active_support/time_with_zone.rb
+++ b/activesupport/lib/active_support/time_with_zone.rb
@@ -329,8 +329,7 @@ module ActiveSupport
# Send the missing method to +time+ instance, and wrap result in a new TimeWithZone with the existing +time_zone+.
def method_missing(sym, *args, &block)
- result = time.__send__(sym, *args, &block)
- result.acts_like?(:time) ? self.class.new(nil, time_zone, result) : result
+ wrap_with_time_zone time.__send__(sym, *args, &block)
end
private
@@ -348,11 +347,22 @@ module ActiveSupport
end
def transfer_time_values_to_utc_constructor(time)
- ::Time.utc_time(time.year, time.month, time.day, time.hour, time.min, time.sec, time.respond_to?(:usec) ? time.usec : 0)
+ usec = time.respond_to?(:nsec) ? Rational(time.nsec, 1000) : (time.respond_to?(:usec) ? time.usec : 0)
+ ::Time.utc_time(time.year, time.month, time.day, time.hour, time.min, time.sec, usec)
end
def duration_of_variable_length?(obj)
ActiveSupport::Duration === obj && obj.parts.any? {|p| p[0].in?([:years, :months, :days]) }
end
+
+ def wrap_with_time_zone(time)
+ if time.acts_like?(:time)
+ self.class.new(nil, time_zone, time)
+ elsif time.is_a?(Range)
+ wrap_with_time_zone(time.begin)..wrap_with_time_zone(time.end)
+ else
+ time
+ end
+ end
end
end
diff --git a/activesupport/lib/active_support/version.rb b/activesupport/lib/active_support/version.rb
index 94c22b0af6..e928403dd2 100644
--- a/activesupport/lib/active_support/version.rb
+++ b/activesupport/lib/active_support/version.rb
@@ -2,7 +2,7 @@ module ActiveSupport
module VERSION #:nodoc:
MAJOR = 3
MINOR = 2
- TINY = 10
+ TINY = 11
PRE = nil
STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
diff --git a/activesupport/test/core_ext/date_ext_test.rb b/activesupport/test/core_ext/date_ext_test.rb
index c040d86327..37bbcc7d39 100644
--- a/activesupport/test/core_ext/date_ext_test.rb
+++ b/activesupport/test/core_ext/date_ext_test.rb
@@ -350,14 +350,14 @@ class DateExtCalculationsTest < ActiveSupport::TestCase
end
def test_end_of_day
- assert_equal Time.local(2005,2,21,23,59,59,999999.999), Date.new(2005,2,21).end_of_day
+ assert_equal Time.local(2005,2,21,23,59,59,Rational(999999999, 1000)), Date.new(2005,2,21).end_of_day
end
def test_end_of_day_when_zone_is_set
zone = ActiveSupport::TimeZone['Eastern Time (US & Canada)']
with_env_tz 'UTC' do
with_tz_default zone do
- assert_equal zone.local(2005,2,21,23,59,59,999999.999), Date.new(2005,2,21).end_of_day
+ assert_equal zone.local(2005,2,21,23,59,59,Rational(999999999, 1000)), Date.new(2005,2,21).end_of_day
assert_equal zone, Date.new(2005,2,21).end_of_day.time_zone
end
end
diff --git a/activesupport/test/core_ext/hash_ext_test.rb b/activesupport/test/core_ext/hash_ext_test.rb
index b5eb049ad4..c3a59540fb 100644
--- a/activesupport/test/core_ext/hash_ext_test.rb
+++ b/activesupport/test/core_ext/hash_ext_test.rb
@@ -733,12 +733,10 @@ class HashToXmlTest < Test::Unit::TestCase
<replies-close-in type="integer">2592000000</replies-close-in>
<written-on type="date">2003-07-16</written-on>
<viewed-at type="datetime">2003-07-16T09:28:00+0000</viewed-at>
- <content type="yaml">--- \n1: should be an integer\n:message: Have a nice day\narray: \n- should-have-dashes: true\n should_have_underscores: true\n</content>
<author-email-address>david@loudthinking.com</author-email-address>
<parent-id></parent-id>
<ad-revenue type="decimal">1.5</ad-revenue>
<optimum-viewing-angle type="float">135</optimum-viewing-angle>
- <resident type="symbol">yes</resident>
</topic>
EOT
@@ -751,12 +749,10 @@ class HashToXmlTest < Test::Unit::TestCase
:replies_close_in => 2592000000,
:written_on => Date.new(2003, 7, 16),
:viewed_at => Time.utc(2003, 7, 16, 9, 28),
- :content => { :message => "Have a nice day", 1 => "should be an integer", "array" => [{ "should-have-dashes" => true, "should_have_underscores" => true }] },
:author_email_address => "david@loudthinking.com",
:parent_id => nil,
:ad_revenue => BigDecimal("1.50"),
:optimum_viewing_angle => 135.0,
- :resident => :yes
}.stringify_keys
assert_equal expected_topic_hash, Hash.from_xml(topic_xml)["topic"]
@@ -770,7 +766,6 @@ class HashToXmlTest < Test::Unit::TestCase
<approved type="boolean"></approved>
<written-on type="date"></written-on>
<viewed-at type="datetime"></viewed-at>
- <content type="yaml"></content>
<parent-id></parent-id>
</topic>
EOT
@@ -781,7 +776,6 @@ class HashToXmlTest < Test::Unit::TestCase
:approved => nil,
:written_on => nil,
:viewed_at => nil,
- :content => nil,
:parent_id => nil
}.stringify_keys
@@ -1008,6 +1002,28 @@ class HashToXmlTest < Test::Unit::TestCase
assert_equal expected_product_hash, Hash.from_xml(product_xml)["product"]
end
+ def test_from_xml_raises_on_disallowed_type_attributes
+ assert_raise Hash::DisallowedType do
+ Hash.from_xml '<product><name type="foo">value</name></product>', %w(foo)
+ end
+ end
+
+ def test_from_xml_disallows_symbol_and_yaml_types_by_default
+ assert_raise Hash::DisallowedType do
+ Hash.from_xml '<product><name type="symbol">value</name></product>'
+ end
+
+ assert_raise Hash::DisallowedType do
+ Hash.from_xml '<product><name type="yaml">value</name></product>'
+ end
+ end
+
+ def test_from_trusted_xml_allows_symbol_and_yaml_types
+ expected = { 'product' => { 'name' => :value }}
+ assert_equal expected, Hash.from_trusted_xml('<product><name type="symbol">value</name></product>')
+ assert_equal expected, Hash.from_trusted_xml('<product><name type="yaml">:value</name></product>')
+ end
+
def test_should_use_default_value_for_unknown_key
hash_wia = HashWithIndifferentAccess.new(3)
assert_equal 3, hash_wia[:new_key]
diff --git a/activesupport/test/core_ext/time_ext_test.rb b/activesupport/test/core_ext/time_ext_test.rb
index 7a818411d0..0d680832ef 100644
--- a/activesupport/test/core_ext/time_ext_test.rb
+++ b/activesupport/test/core_ext/time_ext_test.rb
@@ -109,49 +109,49 @@ class TimeExtCalculationsTest < ActiveSupport::TestCase
end
def test_end_of_day
- assert_equal Time.local(2007,8,12,23,59,59,999999.999), Time.local(2007,8,12,10,10,10).end_of_day
+ assert_equal Time.local(2007,8,12,23,59,59,Rational(999999999, 1000)), Time.local(2007,8,12,10,10,10).end_of_day
with_env_tz 'US/Eastern' do
- assert_equal Time.local(2007,4,2,23,59,59,999999.999), Time.local(2007,4,2,10,10,10).end_of_day, 'start DST'
- assert_equal Time.local(2007,10,29,23,59,59,999999.999), Time.local(2007,10,29,10,10,10).end_of_day, 'ends DST'
+ assert_equal Time.local(2007,4,2,23,59,59,Rational(999999999, 1000)), Time.local(2007,4,2,10,10,10).end_of_day, 'start DST'
+ assert_equal Time.local(2007,10,29,23,59,59,Rational(999999999, 1000)), Time.local(2007,10,29,10,10,10).end_of_day, 'ends DST'
end
with_env_tz 'NZ' do
- assert_equal Time.local(2006,3,19,23,59,59,999999.999), Time.local(2006,3,19,10,10,10).end_of_day, 'ends DST'
- assert_equal Time.local(2006,10,1,23,59,59,999999.999), Time.local(2006,10,1,10,10,10).end_of_day, 'start DST'
+ assert_equal Time.local(2006,3,19,23,59,59,Rational(999999999, 1000)), Time.local(2006,3,19,10,10,10).end_of_day, 'ends DST'
+ assert_equal Time.local(2006,10,1,23,59,59,Rational(999999999, 1000)), Time.local(2006,10,1,10,10,10).end_of_day, 'start DST'
end
end
def test_end_of_week
- assert_equal Time.local(2008,1,6,23,59,59,999999.999), Time.local(2007,12,31,10,10,10).end_of_week
- assert_equal Time.local(2007,9,2,23,59,59,999999.999), Time.local(2007,8,27,0,0,0).end_of_week #monday
- assert_equal Time.local(2007,9,2,23,59,59,999999.999), Time.local(2007,8,28,0,0,0).end_of_week #tuesday
- assert_equal Time.local(2007,9,2,23,59,59,999999.999), Time.local(2007,8,29,0,0,0).end_of_week #wednesday
- assert_equal Time.local(2007,9,2,23,59,59,999999.999), Time.local(2007,8,30,0,0,0).end_of_week #thursday
- assert_equal Time.local(2007,9,2,23,59,59,999999.999), Time.local(2007,8,31,0,0,0).end_of_week #friday
- assert_equal Time.local(2007,9,2,23,59,59,999999.999), Time.local(2007,9,01,0,0,0).end_of_week #saturday
- assert_equal Time.local(2007,9,2,23,59,59,999999.999), Time.local(2007,9,02,0,0,0).end_of_week #sunday
+ assert_equal Time.local(2008,1,6,23,59,59,Rational(999999999, 1000)), Time.local(2007,12,31,10,10,10).end_of_week
+ assert_equal Time.local(2007,9,2,23,59,59,Rational(999999999, 1000)), Time.local(2007,8,27,0,0,0).end_of_week #monday
+ assert_equal Time.local(2007,9,2,23,59,59,Rational(999999999, 1000)), Time.local(2007,8,28,0,0,0).end_of_week #tuesday
+ assert_equal Time.local(2007,9,2,23,59,59,Rational(999999999, 1000)), Time.local(2007,8,29,0,0,0).end_of_week #wednesday
+ assert_equal Time.local(2007,9,2,23,59,59,Rational(999999999, 1000)), Time.local(2007,8,30,0,0,0).end_of_week #thursday
+ assert_equal Time.local(2007,9,2,23,59,59,Rational(999999999, 1000)), Time.local(2007,8,31,0,0,0).end_of_week #friday
+ assert_equal Time.local(2007,9,2,23,59,59,Rational(999999999, 1000)), Time.local(2007,9,01,0,0,0).end_of_week #saturday
+ assert_equal Time.local(2007,9,2,23,59,59,Rational(999999999, 1000)), Time.local(2007,9,02,0,0,0).end_of_week #sunday
end
def test_end_of_hour
- assert_equal Time.local(2005,2,4,19,59,59,999999.999), Time.local(2005,2,4,19,30,10).end_of_hour
+ assert_equal Time.local(2005,2,4,19,59,59,Rational(999999999, 1000)), Time.local(2005,2,4,19,30,10).end_of_hour
end
def test_end_of_month
- assert_equal Time.local(2005,3,31,23,59,59,999999.999), Time.local(2005,3,20,10,10,10).end_of_month
- assert_equal Time.local(2005,2,28,23,59,59,999999.999), Time.local(2005,2,20,10,10,10).end_of_month
- assert_equal Time.local(2005,4,30,23,59,59,999999.999), Time.local(2005,4,20,10,10,10).end_of_month
+ assert_equal Time.local(2005,3,31,23,59,59,Rational(999999999, 1000)), Time.local(2005,3,20,10,10,10).end_of_month
+ assert_equal Time.local(2005,2,28,23,59,59,Rational(999999999, 1000)), Time.local(2005,2,20,10,10,10).end_of_month
+ assert_equal Time.local(2005,4,30,23,59,59,Rational(999999999, 1000)), Time.local(2005,4,20,10,10,10).end_of_month
end
def test_end_of_quarter
- assert_equal Time.local(2007,3,31,23,59,59,999999.999), Time.local(2007,2,15,10,10,10).end_of_quarter
- assert_equal Time.local(2007,3,31,23,59,59,999999.999), Time.local(2007,3,31,0,0,0).end_of_quarter
- assert_equal Time.local(2007,12,31,23,59,59,999999.999), Time.local(2007,12,21,10,10,10).end_of_quarter
- assert_equal Time.local(2007,6,30,23,59,59,999999.999), Time.local(2007,4,1,0,0,0).end_of_quarter
- assert_equal Time.local(2008,6,30,23,59,59,999999.999), Time.local(2008,5,31,0,0,0).end_of_quarter
+ assert_equal Time.local(2007,3,31,23,59,59,Rational(999999999, 1000)), Time.local(2007,2,15,10,10,10).end_of_quarter
+ assert_equal Time.local(2007,3,31,23,59,59,Rational(999999999, 1000)), Time.local(2007,3,31,0,0,0).end_of_quarter
+ assert_equal Time.local(2007,12,31,23,59,59,Rational(999999999, 1000)), Time.local(2007,12,21,10,10,10).end_of_quarter
+ assert_equal Time.local(2007,6,30,23,59,59,Rational(999999999, 1000)), Time.local(2007,4,1,0,0,0).end_of_quarter
+ assert_equal Time.local(2008,6,30,23,59,59,Rational(999999999, 1000)), Time.local(2008,5,31,0,0,0).end_of_quarter
end
def test_end_of_year
- assert_equal Time.local(2007,12,31,23,59,59,999999.999), Time.local(2007,2,22,10,10,10).end_of_year
- assert_equal Time.local(2007,12,31,23,59,59,999999.999), Time.local(2007,12,31,10,10,10).end_of_year
+ assert_equal Time.local(2007,12,31,23,59,59,Rational(999999999, 1000)), Time.local(2007,2,22,10,10,10).end_of_year
+ assert_equal Time.local(2007,12,31,23,59,59,Rational(999999999, 1000)), Time.local(2007,12,31,10,10,10).end_of_year
end
def test_beginning_of_year
@@ -807,24 +807,32 @@ class TimeExtCalculationsTest < ActiveSupport::TestCase
end
def test_all_day
- assert_equal Time.local(2011,6,7,0,0,0)..Time.local(2011,6,7,23,59,59,999999.999), Time.local(2011,6,7,10,10,10).all_day
+ assert_equal Time.local(2011,6,7,0,0,0)..Time.local(2011,6,7,23,59,59,Rational(999999999, 1000)), Time.local(2011,6,7,10,10,10).all_day
+ end
+
+ def test_all_day_with_timezone
+ beginning_of_day = ActiveSupport::TimeWithZone.new(nil, ActiveSupport::TimeZone["Hawaii"], Time.local(2011,6,7,0,0,0))
+ end_of_day = ActiveSupport::TimeWithZone.new(nil, ActiveSupport::TimeZone["Hawaii"], Time.local(2011,6,7,23,59,59,Rational(999999999, 1000)))
+
+ assert_equal beginning_of_day, ActiveSupport::TimeWithZone.new(Time.local(2011,6,7,10,10,10), ActiveSupport::TimeZone["Hawaii"]).all_day.begin
+ assert_equal end_of_day, ActiveSupport::TimeWithZone.new(Time.local(2011,6,7,10,10,10), ActiveSupport::TimeZone["Hawaii"]).all_day.end
end
def test_all_week
- assert_equal Time.local(2011,6,6,0,0,0)..Time.local(2011,6,12,23,59,59,999999.999), Time.local(2011,6,7,10,10,10).all_week
- assert_equal Time.local(2011,6,5,0,0,0)..Time.local(2011,6,11,23,59,59,999999.999), Time.local(2011,6,7,10,10,10).all_week(:sunday)
+ assert_equal Time.local(2011,6,6,0,0,0)..Time.local(2011,6,12,23,59,59,Rational(999999999, 1000)), Time.local(2011,6,7,10,10,10).all_week
+ assert_equal Time.local(2011,6,5,0,0,0)..Time.local(2011,6,11,23,59,59,Rational(999999999, 1000)), Time.local(2011,6,7,10,10,10).all_week(:sunday)
end
def test_all_month
- assert_equal Time.local(2011,6,1,0,0,0)..Time.local(2011,6,30,23,59,59,999999.999), Time.local(2011,6,7,10,10,10).all_month
+ assert_equal Time.local(2011,6,1,0,0,0)..Time.local(2011,6,30,23,59,59,Rational(999999999, 1000)), Time.local(2011,6,7,10,10,10).all_month
end
def test_all_quarter
- assert_equal Time.local(2011,4,1,0,0,0)..Time.local(2011,6,30,23,59,59,999999.999), Time.local(2011,6,7,10,10,10).all_quarter
+ assert_equal Time.local(2011,4,1,0,0,0)..Time.local(2011,6,30,23,59,59,Rational(999999999, 1000)), Time.local(2011,6,7,10,10,10).all_quarter
end
def test_all_year
- assert_equal Time.local(2011,1,1,0,0,0)..Time.local(2011,12,31,23,59,59,999999.999), Time.local(2011,6,7,10,10,10).all_year
+ assert_equal Time.local(2011,1,1,0,0,0)..Time.local(2011,12,31,23,59,59,Rational(999999999, 1000)), Time.local(2011,6,7,10,10,10).all_year
end
protected
diff --git a/activesupport/test/core_ext/time_with_zone_test.rb b/activesupport/test/core_ext/time_with_zone_test.rb
index 84afee6c84..b80a68711c 100644
--- a/activesupport/test/core_ext/time_with_zone_test.rb
+++ b/activesupport/test/core_ext/time_with_zone_test.rb
@@ -80,6 +80,16 @@ class TimeWithZoneTest < Test::Unit::TestCase
ActiveSupport.use_standard_json_time_format = old
end
+ if RUBY_VERSION >= '1.9'
+ def test_nsec
+ local = Time.local(2011,6,7,23,59,59,Rational(999999999, 1000))
+ with_zone = ActiveSupport::TimeWithZone.new(nil, ActiveSupport::TimeZone["Hawaii"], local)
+
+ assert_equal local.nsec, with_zone.nsec
+ assert_equal with_zone.nsec, 999999999
+ end
+ end
+
def test_strftime
assert_equal '1999-12-31 19:00:00 EST -0500', @twz.strftime('%Y-%m-%d %H:%M:%S %Z %z')
end
diff --git a/railties/CHANGELOG.md b/railties/CHANGELOG.md
index 0ddc7ccca7..44533a579c 100644
--- a/railties/CHANGELOG.md
+++ b/railties/CHANGELOG.md
@@ -1,4 +1,9 @@
-## Rails 3.2.11 (unreleased) ##
+## Rails 3.2.12 (unreleased) ##
+
+
+## Rails 3.2.11 (Jan 8, 2013) ##
+
+* No changes.
## Rails 3.2.10 (Jan 2, 2013) ##
@@ -27,6 +32,7 @@
* Update supported ruby versions error message in ruby_version_check.rb *Lihan Li*
+
## Rails 3.2.8 (Aug 9, 2012) ##
* ERB scaffold generator use the `:data => { :confirm => "Text" }` syntax instead of `:confirm`.
diff --git a/railties/lib/rails/version.rb b/railties/lib/rails/version.rb
index 958f24866b..352ecf45c0 100644
--- a/railties/lib/rails/version.rb
+++ b/railties/lib/rails/version.rb
@@ -2,7 +2,7 @@ module Rails
module VERSION #:nodoc:
MAJOR = 3
MINOR = 2
- TINY = 10
+ TINY = 11
PRE = nil
STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
diff --git a/version.rb b/version.rb
index 958f24866b..352ecf45c0 100644
--- a/version.rb
+++ b/version.rb
@@ -2,7 +2,7 @@ module Rails
module VERSION #:nodoc:
MAJOR = 3
MINOR = 2
- TINY = 10
+ TINY = 11
PRE = nil
STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')