aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport
diff options
context:
space:
mode:
Diffstat (limited to 'activesupport')
-rw-r--r--activesupport/CHANGELOG2
-rw-r--r--activesupport/lib/active_support/core_ext/string/output_safety.rb25
-rw-r--r--activesupport/lib/active_support/inflector/methods.rb32
-rw-r--r--activesupport/lib/active_support/values/time_zone.rb2
-rw-r--r--activesupport/test/inflector_test.rb22
-rw-r--r--activesupport/test/inflector_test_cases.rb7
-rw-r--r--activesupport/test/safe_buffer_test.rb41
7 files changed, 85 insertions, 46 deletions
diff --git a/activesupport/CHANGELOG b/activesupport/CHANGELOG
index 18164234a5..038fe63141 100644
--- a/activesupport/CHANGELOG
+++ b/activesupport/CHANGELOG
@@ -1,5 +1,7 @@
*Rails 3.2.0 (unreleased)*
+* Safe strings no longer respond to sub, sub!, gsub, or gsub!. See issue #1555. [Damien Mathieu]
+
* ActiveSupport::OrderedHash is now marked as extractable when using Array#extract_options! [Prem Sichanugrist]
* Added Array#prepend as an alias for Array#unshift and Array#append as an alias for Array#<< [DHH]
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 f111c8e5a3..f364a42354 100644
--- a/activesupport/lib/active_support/core_ext/string/output_safety.rb
+++ b/activesupport/lib/active_support/core_ext/string/output_safety.rb
@@ -75,7 +75,8 @@ end
module ActiveSupport #:nodoc:
class SafeBuffer < String
- UNSAFE_STRING_METHODS = ["capitalize", "chomp", "chop", "delete", "downcase", "gsub", "lstrip", "next", "reverse", "rstrip", "slice", "squeeze", "strip", "sub", "succ", "swapcase", "tr", "tr_s", "upcase"].freeze
+ UNSAFE_STRING_METHODS = ["capitalize", "chomp", "chop", "delete", "downcase", "lstrip", "next", "reverse", "rstrip", "slice", "squeeze", "strip", "succ", "swapcase", "tr", "tr_s", "upcase"].freeze
+ UNAVAILABLE_STRING_METHODS = ["gsub", "sub"]
alias_method :original_concat, :concat
private :original_concat
@@ -143,17 +144,35 @@ module ActiveSupport #:nodoc:
UNSAFE_STRING_METHODS.each do |unsafe_method|
class_eval <<-EOT, __FILE__, __LINE__
- def #{unsafe_method}(*args, &block) # def gsub(*args, &block)
+ def #{unsafe_method}(*args, &block) # def capitalize(*args, &block)
to_str.#{unsafe_method}(*args, &block) # to_str.gsub(*args, &block)
end # end
- def #{unsafe_method}!(*args) # def gsub!(*args)
+ def #{unsafe_method}!(*args) # def capitalize!(*args)
@dirty = true # @dirty = true
super # super
end # end
EOT
end
+ UNAVAILABLE_STRING_METHODS.each do |unavailable_method|
+ class_eval <<-EOT, __FILE__, __LINE__
+ # def gsub(*args)
+ # raise NoMethodError, "gsub cannot be used with a safe string. You should use object.to_str.gsub"
+ # end
+ def #{unavailable_method}(*args)
+ raise NoMethodError, "#{unavailable_method} cannot be used with a safe string. You should use object.to_str.#{unavailable_method}"
+ end
+
+ # def gsub!(*args)
+ # raise NoMethodError, "gsub! cannot be used with a safe string. You should use object.to_str.gsub!"
+ # end
+ def #{unavailable_method}!(*args)
+ raise NoMethodError, "#{unavailable_method}! cannot be used with a safe string. You should use object.to_str.#{unavailable_method}!"
+ end
+ EOT
+ end
+
protected
def dirty?
diff --git a/activesupport/lib/active_support/inflector/methods.rb b/activesupport/lib/active_support/inflector/methods.rb
index 423b5abd20..e1aba44813 100644
--- a/activesupport/lib/active_support/inflector/methods.rb
+++ b/activesupport/lib/active_support/inflector/methods.rb
@@ -21,7 +21,8 @@ module ActiveSupport
# "words".pluralize # => "words"
# "CamelOctopus".pluralize # => "CamelOctopi"
def pluralize(word)
- result = word.to_s.dup
+ word = deprecate_symbol(word)
+ result = word.to_str.dup
if word.empty? || inflections.uncountables.include?(result.downcase)
result
@@ -40,7 +41,8 @@ module ActiveSupport
# "word".singularize # => "word"
# "CamelOctopi".singularize # => "CamelOctopus"
def singularize(word)
- result = word.to_s.dup
+ word = deprecate_symbol(word)
+ result = word.to_str.dup
if inflections.uncountables.any? { |inflection| result =~ /\b(#{inflection})\Z/i }
result
@@ -66,7 +68,8 @@ module ActiveSupport
#
# "SSLError".underscore.camelize # => "SslError"
def camelize(term, uppercase_first_letter = true)
- string = term.to_s
+ term = deprecate_symbol(term)
+ string = term.to_str
if uppercase_first_letter
string = string.sub(/^[a-z\d]*/) { inflections.acronyms[$&] || $&.capitalize }
else
@@ -88,7 +91,8 @@ module ActiveSupport
#
# "SSLError".underscore.camelize # => "SslError"
def underscore(camel_cased_word)
- word = camel_cased_word.to_s.dup
+ camel_cased_word = deprecate_symbol(camel_cased_word)
+ word = camel_cased_word.to_str.dup
word.gsub!(/::/, '/')
word.gsub!(/(?:([A-Za-z\d])|^)(#{inflections.acronym_regex})(?=\b|[^a-z])/) { "#{$1}#{$1 && '_'}#{$2.downcase}" }
word.gsub!(/([A-Z\d]+)([A-Z][a-z])/,'\1_\2')
@@ -105,7 +109,8 @@ module ActiveSupport
# "employee_salary" # => "Employee salary"
# "author_id" # => "Author"
def humanize(lower_case_and_underscored_word)
- result = lower_case_and_underscored_word.to_s.dup
+ lower_case_and_underscored_word = deprecate_symbol(lower_case_and_underscored_word)
+ result = lower_case_and_underscored_word.to_str.dup
inflections.humans.each { |(rule, replacement)| break if result.gsub!(rule, replacement) }
result.gsub!(/_id$/, "")
result.gsub(/(_)?([a-z\d]*)/i) { "#{$1 && ' '}#{inflections.acronyms[$2] || $2.downcase}" }.gsub(/^\w/) { $&.upcase }
@@ -148,8 +153,9 @@ module ActiveSupport
# Singular names are not handled correctly:
# "business".classify # => "Busines"
def classify(table_name)
+ table_name = deprecate_symbol(table_name)
# strip out any leading schema name
- camelize(singularize(table_name.to_s.sub(/.*\./, '')))
+ camelize(singularize(table_name.to_str.sub(/.*\./, '')))
end
# Replaces underscores with dashes in the string.
@@ -157,7 +163,8 @@ module ActiveSupport
# Example:
# "puni_puni" # => "puni-puni"
def dasherize(underscored_word)
- underscored_word.gsub(/_/, '-')
+ underscored_word = deprecate_symbol(underscored_word)
+ underscored_word.to_str.gsub(/_/, '-')
end
# Removes the module part from the expression in the string.
@@ -166,7 +173,8 @@ module ActiveSupport
# "ActiveRecord::CoreExtensions::String::Inflections".demodulize # => "Inflections"
# "Inflections".demodulize # => "Inflections"
def demodulize(class_name_in_module)
- class_name_in_module.to_s.gsub(/^.*::/, '')
+ class_name_in_module = deprecate_symbol(class_name_in_module)
+ class_name_in_module.to_str.gsub(/^.*::/, '')
end
# Creates a foreign key name from a class name.
@@ -246,5 +254,13 @@ module ActiveSupport
end
end
end
+
+ def deprecate_symbol(symbol)
+ if symbol.is_a?(Symbol)
+ symbol = symbol.to_s
+ ActiveSupport::Deprecation.warn("Using symbols in inflections is deprecated. Please use to_s to have a string.")
+ end
+ symbol
+ end
end
end
diff --git a/activesupport/lib/active_support/values/time_zone.rb b/activesupport/lib/active_support/values/time_zone.rb
index 4fb487ade1..35f400f9df 100644
--- a/activesupport/lib/active_support/values/time_zone.rb
+++ b/activesupport/lib/active_support/values/time_zone.rb
@@ -371,7 +371,7 @@ module ActiveSupport
protected
def require_tzinfo
- require 'tzinfo'
+ require 'tzinfo' unless defined?(::TZInfo)
rescue LoadError
$stderr.puts "You don't have tzinfo installed in your application. Please add it to your Gemfile and run bundle install"
raise
diff --git a/activesupport/test/inflector_test.rb b/activesupport/test/inflector_test.rb
index b9e299af75..6484811d34 100644
--- a/activesupport/test/inflector_test.rb
+++ b/activesupport/test/inflector_test.rb
@@ -10,7 +10,7 @@ module Ace
end
end
-class InflectorTest < Test::Unit::TestCase
+class InflectorTest < ActiveSupport::TestCase
include InflectorTestCases
def test_pluralize_plurals
@@ -248,12 +248,6 @@ class InflectorTest < Test::Unit::TestCase
end
end
- def test_classify_with_symbol
- assert_nothing_raised do
- assert_equal 'FooBar', ActiveSupport::Inflector.classify(:foo_bars)
- end
- end
-
def test_classify_with_leading_schema_name
assert_equal 'FooBar', ActiveSupport::Inflector.classify('schema.foo_bar')
end
@@ -319,12 +313,6 @@ class InflectorTest < Test::Unit::TestCase
end
end
- def test_symbol_to_lower_camel
- SymbolToLowerCamel.each do |symbol, lower_camel|
- assert_equal(lower_camel, ActiveSupport::Inflector.camelize(symbol, false))
- end
- end
-
%w{plurals singulars uncountables humans}.each do |inflection_type|
class_eval <<-RUBY, __FILE__, __LINE__ + 1
def test_clear_#{inflection_type}
@@ -380,6 +368,14 @@ class InflectorTest < Test::Unit::TestCase
ActiveSupport::Inflector.inflections.instance_variable_set :@humans, cached_values[3]
end
+ [:pluralize, :singularize, :camelize, :underscore, :humanize, :titleize, :tableize, :classify, :dasherize, :demodulize].each do |method|
+ test "should deprecate symbols on #{method}" do
+ assert_deprecated(/Using symbols in inflections is deprecated/) do
+ ActiveSupport::Inflector.send(method, :foo)
+ end
+ end
+ end
+
Irregularities.each do |irregularity|
singular, plural = *irregularity
ActiveSupport::Inflector.inflections do |inflect|
diff --git a/activesupport/test/inflector_test_cases.rb b/activesupport/test/inflector_test_cases.rb
index 0cb1f70657..62e0ccd355 100644
--- a/activesupport/test/inflector_test_cases.rb
+++ b/activesupport/test/inflector_test_cases.rb
@@ -120,13 +120,6 @@ module InflectorTestCases
"area51_controller" => "area51Controller"
}
- SymbolToLowerCamel = {
- :product => 'product',
- :special_guest => 'specialGuest',
- :application_controller => 'applicationController',
- :area51_controller => 'area51Controller'
- }
-
CamelToUnderscoreWithoutReverse = {
"HTMLTidy" => "html_tidy",
"HTMLTidyGenerator" => "html_tidy_generator",
diff --git a/activesupport/test/safe_buffer_test.rb b/activesupport/test/safe_buffer_test.rb
index 8f77999d25..f2cd67749a 100644
--- a/activesupport/test/safe_buffer_test.rb
+++ b/activesupport/test/safe_buffer_test.rb
@@ -67,42 +67,41 @@ class SafeBufferTest < ActiveSupport::TestCase
assert_equal "my_test", str
end
- test "Should not return safe buffer from gsub" do
- altered_buffer = @buffer.gsub('', 'asdf')
- assert_equal 'asdf', altered_buffer
+ test "Should not return safe buffer from capitalize" do
+ altered_buffer = "asdf".html_safe.capitalize
+ assert_equal 'Asdf', altered_buffer
assert !altered_buffer.html_safe?
end
test "Should not return safe buffer from gsub!" do
- @buffer.gsub!('', 'asdf')
- assert_equal 'asdf', @buffer
- assert !@buffer.html_safe?
+ string = "asdf"
+ string.capitalize!
+ assert_equal 'Asdf', string
+ assert !string.html_safe?
end
test "Should escape dirty buffers on add" do
clean = "hello".html_safe
- @buffer.gsub!('', '<>')
- assert_equal "hello&lt;&gt;", clean + @buffer
+ assert_equal "hello&lt;&gt;", clean + '<>'
end
test "Should concat as a normal string when dirty" do
clean = "hello".html_safe
- @buffer.gsub!('', '<>')
- assert_equal "<>hello", @buffer + clean
+ assert_equal "<>hello", '<>' + clean
end
test "Should preserve dirty? status on copy" do
- @buffer.gsub!('', '<>')
- assert !@buffer.dup.html_safe?
+ dirty = "<>"
+ assert !dirty.dup.html_safe?
end
test "Should raise an error when safe_concat is called on dirty buffers" do
- @buffer.gsub!('', '<>')
+ @buffer.capitalize!
assert_raise ActiveSupport::SafeBuffer::SafeConcatError do
@buffer.safe_concat "BUSTED"
end
end
-
+
test "should not fail if the returned object is not a string" do
assert_kind_of NilClass, @buffer.slice("chipchop")
end
@@ -112,4 +111,18 @@ class SafeBufferTest < ActiveSupport::TestCase
assert_not_nil dirty
assert !dirty
end
+
+ ["gsub", "sub"].each do |unavailable_method|
+ test "should raise on #{unavailable_method}" do
+ assert_raise NoMethodError, "#{unavailable_method} cannot be used with a safe string. You should use object.to_str.#{unavailable_method}" do
+ @buffer.send(unavailable_method, '', '<>')
+ end
+ end
+
+ test "should raise on #{unavailable_method}!" do
+ assert_raise NoMethodError, "#{unavailable_method}! cannot be used with a safe string. You should use object.to_str.#{unavailable_method}!" do
+ @buffer.send("#{unavailable_method}!", '', '<>')
+ end
+ end
+ end
end