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:
parent
1844572fd1
commit
594603b45f
2 changed files with 55 additions and 18 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
test "Should not return safe buffer from gsub!" do
|
||||
@buffer.gsub!('', 'asdf')
|
||||
end
|
||||
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<>", 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
|
||||
|
|
Loading…
Reference in a new issue