diff options
Diffstat (limited to 'activesupport')
-rw-r--r-- | activesupport/lib/active_support/core_ext/string.rb | 3 | ||||
-rw-r--r-- | activesupport/lib/active_support/core_ext/string/output_safety.rb | 43 | ||||
-rw-r--r-- | activesupport/test/core_ext/string_ext_test.rb | 86 |
3 files changed, 131 insertions, 1 deletions
diff --git a/activesupport/lib/active_support/core_ext/string.rb b/activesupport/lib/active_support/core_ext/string.rb index d06a5a32fb..6c52f12712 100644 --- a/activesupport/lib/active_support/core_ext/string.rb +++ b/activesupport/lib/active_support/core_ext/string.rb @@ -7,4 +7,5 @@ require 'active_support/core_ext/string/access' require 'active_support/core_ext/string/iterators' require 'active_support/core_ext/string/xchar' require 'active_support/core_ext/string/behavior' -require 'active_support/core_ext/string/interpolation'
\ No newline at end of file +require 'active_support/core_ext/string/interpolation' +require 'active_support/core_ext/string/output_safety'
\ No newline at end of file diff --git a/activesupport/lib/active_support/core_ext/string/output_safety.rb b/activesupport/lib/active_support/core_ext/string/output_safety.rb new file mode 100644 index 0000000000..2cca4763f4 --- /dev/null +++ b/activesupport/lib/active_support/core_ext/string/output_safety.rb @@ -0,0 +1,43 @@ +class String + def html_safe? + defined?(@_rails_html_safe) && @_rails_html_safe + end + + def html_safe! + @_rails_html_safe = true + self + end + + def html_safe + dup.html_safe! + end + + alias original_plus + + def +(other) + result = original_plus(other) + if html_safe? && also_html_safe?(other) + result.html_safe! + else + result + end + end + + alias original_concat << + def <<(other) + result = original_concat(other) + unless html_safe? && also_html_safe?(other) + @_rails_html_safe = false + end + result + end + + def concat(other) + self << other + end + + private + def also_html_safe?(other) + other.respond_to?(:html_safe?) && other.html_safe? + end + +end
\ No newline at end of file diff --git a/activesupport/test/core_ext/string_ext_test.rb b/activesupport/test/core_ext/string_ext_test.rb index db9073e298..584a41b631 100644 --- a/activesupport/test/core_ext/string_ext_test.rb +++ b/activesupport/test/core_ext/string_ext_test.rb @@ -356,3 +356,89 @@ class StringBytesizeTest < Test::Unit::TestCase assert_equal 3, 'foo'.bytesize end end + +class OutputSafetyTest < ActiveSupport::TestCase + def setup + @string = "hello" + end + + test "A string is unsafe by default" do + assert !@string.html_safe? + end + + test "A string can be marked safe" do + @string.html_safe! + assert @string.html_safe? + end + + test "Marking a string safe returns the string" do + assert_equal @string, @string.html_safe! + end + + test "Adding a safe string to another safe string returns a safe string" do + @other_string = "other".html_safe! + @string.html_safe! + @combination = @other_string + @string + + assert_equal "otherhello", @combination + assert @combination.html_safe? + end + + test "Adding an unsafe string to a safe string returns an unsafe string" do + @other_string = "other".html_safe! + @combination = @other_string + @string + @other_combination = @string + @other_string + + assert_equal "otherhello", @combination + assert_equal "helloother", @other_combination + + assert !@combination.html_safe? + assert !@other_combination.html_safe? + end + + test "Concatting safe onto unsafe yields unsafe" do + @other_string = "other" + @string.html_safe! + + @other_string.concat(@string) + assert !@other_string.html_safe? + end + + test "Concatting unsafe onto safe yields unsafe" do + @other_string = "other".html_safe! + + @other_string.concat(@string) + assert !@other_string.html_safe? + end + + test "Concatting safe onto safe yields safe" do + @other_string = "other".html_safe! + @string.html_safe! + + @other_string.concat(@string) + assert @other_string.html_safe? + end + + test "Concatting safe onto unsafe with << yields unsafe" do + @other_string = "other" + @string.html_safe! + + @other_string << @string + assert !@other_string.html_safe? + end + + test "Concatting unsafe onto safe with << yields unsafe" do + @other_string = "other".html_safe! + + @other_string << @string + assert !@other_string.html_safe? + end + + test "Concatting safe onto safe with << yields safe" do + @other_string = "other".html_safe! + @string.html_safe! + + @other_string << @string + assert @other_string.html_safe? + end +end |