aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport
diff options
context:
space:
mode:
Diffstat (limited to 'activesupport')
-rw-r--r--activesupport/lib/active_support/core_ext/date_time/calculations.rb6
-rw-r--r--activesupport/lib/active_support/core_ext/hash/conversions.rb2
-rw-r--r--activesupport/lib/active_support/core_ext/module/delegation.rb42
-rw-r--r--activesupport/lib/active_support/core_ext/range/each.rb3
-rw-r--r--activesupport/lib/active_support/core_ext/string/output_safety.rb24
-rw-r--r--activesupport/lib/active_support/values/time_zone.rb1
-rw-r--r--activesupport/test/abstract_unit.rb2
-rw-r--r--activesupport/test/core_ext/module_test.rb10
-rw-r--r--activesupport/test/core_ext/range_ext_test.rb4
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>&quot;</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