mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Avoid infinite recursion when bad values are passed to tz aware fields
We had previously updated this to attempt to map over whatever was passed in, so that additional types like range and array could benefit from this behavior without the time zone converter having to deal with every known type. However, the default behavior of a type is to just yield the given value to `map`, which means that if we don't actually know how to handle a value, we'll just recurse infinitely. Since both uses of `map` in this case occur in cases where we know receiving the same object will recurse, we can just break on reference equality. Fixes #23241.
This commit is contained in:
parent
f7775c74d0
commit
5bb26008ce
2 changed files with 19 additions and 2 deletions
|
@ -20,7 +20,7 @@ module ActiveRecord
|
|||
nil
|
||||
end
|
||||
else
|
||||
map(super) { |t| cast(t) }
|
||||
map_avoiding_infinite_recursion(super) { |v| cast(v) }
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -34,13 +34,23 @@ module ActiveRecord
|
|||
elsif value.is_a?(::Float)
|
||||
value
|
||||
else
|
||||
map(value) { |v| convert_time_to_time_zone(v) }
|
||||
map_avoiding_infinite_recursion(value) { |v| convert_time_to_time_zone(v) }
|
||||
end
|
||||
end
|
||||
|
||||
def set_time_zone_without_conversion(value)
|
||||
::Time.zone.local_to_utc(value).in_time_zone
|
||||
end
|
||||
|
||||
def map_avoiding_infinite_recursion(value)
|
||||
map(value) do |v|
|
||||
if value.equal?(v)
|
||||
nil
|
||||
else
|
||||
yield(value)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
extend ActiveSupport::Concern
|
||||
|
|
|
@ -714,6 +714,13 @@ class AttributeMethodsTest < ActiveRecord::TestCase
|
|||
end
|
||||
end
|
||||
|
||||
def test_time_zone_aware_attributes_dont_recurse_infinitely_on_invalid_values
|
||||
in_time_zone "Pacific Time (US & Canada)" do
|
||||
record = @target.new(bonus_time: [])
|
||||
assert_equal nil, record.bonus_time
|
||||
end
|
||||
end
|
||||
|
||||
def test_setting_time_zone_conversion_for_attributes_should_write_value_on_class_variable
|
||||
Topic.skip_time_zone_conversion_for_attributes = [:field_a]
|
||||
Minimalistic.skip_time_zone_conversion_for_attributes = [:field_b]
|
||||
|
|
Loading…
Reference in a new issue