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 e3fa528efb419..4089b02d4503d 100644 --- a/activesupport/lib/active_support/core_ext/string/output_safety.rb +++ b/activesupport/lib/active_support/core_ext/string/output_safety.rb @@ -98,19 +98,31 @@ def initialize end end + def [](*args) + return super if args.size < 2 + + if html_safe? + new_safe_buffer = super + new_safe_buffer.instance_eval { @html_safe = true } + new_safe_buffer + else + to_str[*args] + end + end + def safe_concat(value) - raise SafeConcatError if dirty? + raise SafeConcatError unless html_safe? original_concat(value) end def initialize(*) - @dirty = false + @html_safe = true super end def initialize_copy(other) super - @dirty = other.dirty? + @html_safe = other.html_safe? end def clone_empty @@ -120,7 +132,7 @@ def clone_empty end def concat(value) - if dirty? || value.html_safe? + if !html_safe? || value.html_safe? super(value) else super(ERB::Util.h(value)) @@ -133,7 +145,7 @@ def +(other) end def html_safe? - !dirty? + defined?(@html_safe) && @html_safe end def to_s @@ -161,18 +173,12 @@ def #{unsafe_method}(*args, &block) # def capitalize(*args, &block) end # end def #{unsafe_method}!(*args) # def capitalize!(*args) - @dirty = true # @dirty = true + @html_safe = false # @html_safe = false super # super end # end EOT end end - - protected - - def dirty? - @dirty - end end end diff --git a/activesupport/test/safe_buffer_test.rb b/activesupport/test/safe_buffer_test.rb index e731f1c2e7cd1..25c95f2a2f365 100644 --- a/activesupport/test/safe_buffer_test.rb +++ b/activesupport/test/safe_buffer_test.rb @@ -89,25 +89,32 @@ def test_titleize assert_equal "hello<>", clean + @buffer end - test "Should concat as a normal string when dirty" do + test "Should concat as a normal string when safe" do clean = "hello".html_safe @buffer.gsub!('', '<>') assert_equal "<>hello", @buffer + clean end - test "Should preserve dirty? status on copy" do + test "Should preserve html_safe? status on copy" do @buffer.gsub!('', '<>') assert !@buffer.dup.html_safe? end - test "Should raise an error when safe_concat is called on dirty buffers" do + test "Should return safe buffer when added with another safe buffer" do + clean = "') + + # calling gsub! makes the dirty flag true + assert !x.html_safe?, "should not be safe" + + # getting a slice of it + y = x[0..-1] + + # should still be unsafe + assert !y.html_safe?, "should not be safe" + end end