diff options
Diffstat (limited to 'activesupport')
9 files changed, 57 insertions, 37 deletions
diff --git a/activesupport/lib/active_support/core_ext/date_time/calculations.rb b/activesupport/lib/active_support/core_ext/date_time/calculations.rb index 8e5d723074..73ad0aa097 100644 --- a/activesupport/lib/active_support/core_ext/date_time/calculations.rb +++ b/activesupport/lib/active_support/core_ext/date_time/calculations.rb @@ -151,7 +151,11 @@ class DateTime # Layers additional behavior on DateTime#<=> so that Time and # ActiveSupport::TimeWithZone instances can be compared with a DateTime. def <=>(other) - super other.to_datetime + if other.respond_to? :to_datetime + super other.to_datetime + else + nil + end end end diff --git a/activesupport/lib/active_support/core_ext/hash/conversions.rb b/activesupport/lib/active_support/core_ext/hash/conversions.rb index 2684c772ea..7bea461c77 100644 --- a/activesupport/lib/active_support/core_ext/hash/conversions.rb +++ b/activesupport/lib/active_support/core_ext/hash/conversions.rb @@ -105,7 +105,7 @@ class Hash # hash = Hash.from_xml(xml) # # => {"hash"=>{"foo"=>1, "bar"=>2}} # - # DisallowedType is raise if the XML contains attributes with <tt>type="yaml"</tt> or + # DisallowedType is raised if the XML contains attributes with <tt>type="yaml"</tt> or # <tt>type="symbol"</tt>. Use <tt>Hash.from_trusted_xml</tt> to parse this XML. def from_xml(xml, disallowed_types = nil) ActiveSupport::XMLConverter.new(xml, disallowed_types).to_h diff --git a/activesupport/lib/active_support/core_ext/module/delegation.rb b/activesupport/lib/active_support/core_ext/module/delegation.rb index 58146cdf7a..f855833a24 100644 --- a/activesupport/lib/active_support/core_ext/module/delegation.rb +++ b/activesupport/lib/active_support/core_ext/module/delegation.rb @@ -178,30 +178,32 @@ class Module # whereas conceptually, from the user point of view, the delegator should # be doing one call. if allow_nil - module_eval(<<-EOS, file, line - 3) - def #{method_prefix}#{method}(#{definition}) # def customer_name(*args, &block) - _ = #{to} # _ = client - if !_.nil? || nil.respond_to?(:#{method}) # if !_.nil? || nil.respond_to?(:name) - _.#{method}(#{definition}) # _.name(*args, &block) - end # end - end # end - EOS + method_def = [ + "def #{method_prefix}#{method}(#{definition})", # def customer_name(*args, &block) + "_ = #{to}", # _ = client + "if !_.nil? || nil.respond_to?(:#{method})", # if !_.nil? || nil.respond_to?(:name) + " _.#{method}(#{definition})", # _.name(*args, &block) + "end", # end + "end" # end + ].join ';' else exception = %(raise DelegationError, "#{self}##{method_prefix}#{method} delegated to #{to}.#{method}, but #{to} is nil: \#{self.inspect}") - module_eval(<<-EOS, file, line - 2) - def #{method_prefix}#{method}(#{definition}) # def customer_name(*args, &block) - _ = #{to} # _ = client - _.#{method}(#{definition}) # _.name(*args, &block) - rescue NoMethodError => e # rescue NoMethodError => e - if _.nil? && e.name == :#{method} # if _.nil? && e.name == :name - #{exception} # # add helpful message to the exception - else # else - raise # raise - end # end - end # end - EOS + method_def = [ + "def #{method_prefix}#{method}(#{definition})", # def customer_name(*args, &block) + " _ = #{to}", # _ = client + " _.#{method}(#{definition})", # _.name(*args, &block) + "rescue NoMethodError => e", # rescue NoMethodError => e + " if _.nil? && e.name == :#{method}", # if _.nil? && e.name == :name + " #{exception}", # # add helpful message to the exception + " else", # else + " raise", # raise + " end", # end + "end" # end + ].join ';' end + + module_eval(method_def, file, line) end end end diff --git a/activesupport/lib/active_support/core_ext/range/each.rb b/activesupport/lib/active_support/core_ext/range/each.rb index d51ea2e944..ecef78f55f 100644 --- a/activesupport/lib/active_support/core_ext/range/each.rb +++ b/activesupport/lib/active_support/core_ext/range/each.rb @@ -1,5 +1,4 @@ require 'active_support/core_ext/module/aliasing' -require 'active_support/core_ext/object/acts_like' class Range #:nodoc: @@ -17,7 +16,7 @@ class Range #:nodoc: private def ensure_iteration_allowed - if first.acts_like?(:time) + if first.is_a?(Time) raise TypeError, "can't iterate from #{first.class}" end end diff --git a/activesupport/lib/active_support/core_ext/string/output_safety.rb b/activesupport/lib/active_support/core_ext/string/output_safety.rb index 1b20507c0b..eb02b6a442 100644 --- a/activesupport/lib/active_support/core_ext/string/output_safety.rb +++ b/activesupport/lib/active_support/core_ext/string/output_safety.rb @@ -70,9 +70,20 @@ class ERB # them inside a script tag to avoid XSS vulnerability: # # <script> - # var currentUser = <%= json_escape current_user.to_json %>; + # var currentUser = <%= raw json_escape(current_user.to_json) %>; # </script> # + # It is necessary to +raw+ the result of +json_escape+, so that quotation marks + # don't get converted to <tt>"</tt> entities. +json_escape+ doesn't + # automatically flag the result as HTML safe, since the raw value is unsafe to + # use inside HTML attributes. + # + # If you need to output JSON elsewhere in your HTML, you can just do something + # like this, as any unsafe characters (including quotation marks) will be + # automatically escaped for you: + # + # <div data-user-info="<%= current_user.to_json %>">...</div> + # # WARNING: this helper only works with valid JSON. Using this on non-JSON values # will open up serious XSS vulnerabilities. For example, if you replace the # +current_user.to_json+ in the example above with user input instead, the browser @@ -88,17 +99,6 @@ class ERB # is recommended that you always apply this helper (other libraries, such as the # JSON gem, do not provide this kind of protection by default; also some gems # might override +to_json+ to bypass Active Support's encoder). - # - # The output of this helper method is marked as HTML safe so that you can directly - # include it inside a <tt><script></tt> tag as shown above. - # - # However, it is NOT safe to use the output of this inside an HTML attribute, - # because quotation marks are not escaped. Doing so might break your page's layout. - # If you intend to use this inside an HTML attribute, you should use the - # +html_escape+ helper (or its +h+ alias) instead: - # - # <div data-user-info="<%= h current_user.to_json %>">...</div> - # def json_escape(s) result = s.to_s.gsub(JSON_ESCAPE_REGEXP, JSON_ESCAPE) s.html_safe? ? result.html_safe : result diff --git a/activesupport/lib/active_support/values/time_zone.rb b/activesupport/lib/active_support/values/time_zone.rb index 8ca4973162..beaac42fa1 100644 --- a/activesupport/lib/active_support/values/time_zone.rb +++ b/activesupport/lib/active_support/values/time_zone.rb @@ -234,6 +234,7 @@ module ActiveSupport # Compare this time zone to the parameter. The two are compared first on # their offsets, and then by name. def <=>(zone) + return unless zone.respond_to? :utc_offset result = (utc_offset <=> zone.utc_offset) result = (name <=> zone.name) if result == 0 result diff --git a/activesupport/test/abstract_unit.rb b/activesupport/test/abstract_unit.rb index 1dfa3833f0..0b393e0c7a 100644 --- a/activesupport/test/abstract_unit.rb +++ b/activesupport/test/abstract_unit.rb @@ -34,5 +34,5 @@ end # Skips the current run on JRuby using Minitest::Assertions#skip def jruby_skip(message = '') - skip message if RUBY_ENGINE == 'jruby' + skip message if defined?(JRUBY_VERSION) end diff --git a/activesupport/test/core_ext/module_test.rb b/activesupport/test/core_ext/module_test.rb index 5b99fae411..4680fe5dfe 100644 --- a/activesupport/test/core_ext/module_test.rb +++ b/activesupport/test/core_ext/module_test.rb @@ -245,6 +245,16 @@ class ModuleTest < ActiveSupport::TestCase end end + def test_delegation_line_number + file, line = Someone.instance_method(:foo).source_location + assert_equal Someone::FAILED_DELEGATE_LINE, line + end + + def test_delegate_line_with_nil + file, line = Someone.instance_method(:bar).source_location + assert_equal Someone::FAILED_DELEGATE_LINE_2, line + end + def test_delegation_exception_backtrace someone = Someone.new("foo", "bar") someone.foo diff --git a/activesupport/test/core_ext/range_ext_test.rb b/activesupport/test/core_ext/range_ext_test.rb index 6d6afc85c4..150e6b65fb 100644 --- a/activesupport/test/core_ext/range_ext_test.rb +++ b/activesupport/test/core_ext/range_ext_test.rb @@ -112,4 +112,8 @@ class RangeTest < ActiveSupport::TestCase end end + def test_date_time_with_each + datetime = DateTime.now + assert ((datetime - 1.hour)..datetime).each {} + end end |