1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Fix safe buffer by adding a dirty status.

This commit is contained in:
José Valim 2011-06-16 08:38:56 -03:00
parent 1844572fd1
commit 594603b45f
2 changed files with 55 additions and 18 deletions

View file

@ -76,10 +76,24 @@ 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
# TODO: Should safe_concat check if the current buffer is dirty or not?
# We should probably raise as it would mean we are adding concatenating
# to something that is safe but it actually isn't.
alias safe_concat concat
def initialize(*)
@dirty = false
super
end
def initialize_copy(other)
super
@dirty = other.dirty?
end
def concat(value)
if value.html_safe?
if dirty? || value.html_safe?
super(value)
else
super(ERB::Util.h(value))
@ -92,11 +106,7 @@ module ActiveSupport #:nodoc:
end
def html_safe?
true
end
def html_safe
self
!dirty?
end
def to_s
@ -113,7 +123,6 @@ module ActiveSupport #:nodoc:
def to_yaml(*args)
return super() if defined?(YAML::ENGINE) && !YAML::ENGINE.syck?
to_str.to_yaml(*args)
end
@ -124,18 +133,21 @@ module ActiveSupport #:nodoc:
end
def #{unsafe_method}!(*args)
raise TypeError, "Cannot modify SafeBuffer in place"
@dirty = true
super
end
EOT
end
protected
def dirty?
@dirty
end
end
end
class String
def html_safe!
raise "You can't call html_safe! on a String"
end
def html_safe
ActiveSupport::SafeBuffer.new(self)
end

View file

@ -4,6 +4,7 @@ begin
rescue LoadError
end
require 'active_support/core_ext/string/inflections'
require 'yaml'
class SafeBufferTest < ActiveSupport::TestCase
@ -45,7 +46,7 @@ class SafeBufferTest < ActiveSupport::TestCase
assert_equal ActiveSupport::SafeBuffer, new_buffer.class
end
def test_to_yaml
test "Should be converted to_yaml" do
str = 'hello!'
buf = ActiveSupport::SafeBuffer.new str
yaml = buf.to_yaml
@ -54,22 +55,46 @@ class SafeBufferTest < ActiveSupport::TestCase
assert_equal 'hello!', YAML.load(yaml)
end
def test_nested
test "Should work in nested to_yaml conversion" do
str = 'hello!'
data = { 'str' => ActiveSupport::SafeBuffer.new(str) }
yaml = YAML.dump data
assert_equal({'str' => str}, YAML.load(yaml))
end
test "Should work with underscore" do
str = "MyTest".html_safe.underscore
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
assert !altered_buffer.html_safe?
end
test "Should not allow gsub! on safe buffers" do
assert_raise TypeError do
@buffer.gsub!('', 'asdf')
end
test "Should not return safe buffer from gsub!" do
@buffer.gsub!('', 'asdf')
assert_equal 'asdf', @buffer
assert !@buffer.html_safe?
end
test "Should escape dirty buffers on add" do
dirty = @buffer
clean = "hello".html_safe
@buffer.gsub!('', '<>')
assert_equal "hello&lt;&gt;", clean + @buffer
end
test "Should concat as a normal string when dirty" do
dirty = @buffer
clean = "hello".html_safe
@buffer.gsub!('', '<>')
assert_equal "<>hello", @buffer + clean
end
test "Should preserve dirty? status on copy" do
@buffer.gsub!('', '<>')
assert !@buffer.dup.html_safe?
end
end