Skip to content
Browse files

Ensure that the strings returned by SafeBuffer#gsub and friends aren'…

…t considered html_safe?

Also make sure that the versions of those methods which modify a string in place such as gsub! can't be called on safe buffers at all.

Conflicts:

	activesupport/test/safe_buffer_test.rb
  • Loading branch information...
1 parent 7d1782a commit 1300c034775a5d52ad9141fdf5bbdbb9159df96a @NZKoz NZKoz committed with tenderlove Jun 8, 2011
View
13 activesupport/lib/active_support/core_ext/string/output_safety.rb
@@ -74,6 +74,7 @@ def html_safe?
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
alias safe_concat concat
def concat(value)
@@ -110,6 +111,18 @@ def to_yaml(*args)
to_str.to_yaml(*args)
end
+
+ for unsafe_method in UNSAFE_STRING_METHODS
+ class_eval <<-EOT, __FILE__, __LINE__
+ def #{unsafe_method}(*args)
+ super.to_str
+ end
+
+ def #{unsafe_method}!(*args)
+ raise TypeError, "Cannot modify SafeBuffer in place"
+ end
+ EOT
+ end
end
end
View
12 activesupport/test/safe_buffer_test.rb
@@ -60,4 +60,16 @@ def test_nested
yaml = YAML.dump data
assert_equal({'str' => str}, YAML.load(yaml))
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
+ end
end

2 comments on commit 1300c03

@yyyc514

How would capitalize, strip, downcase, upcase, etc. change a safe buffer in such a way that it was no longer safe? gsub and some others I can perfectly understand, but...?

@steveklabnik
Ruby on Rails member

Proving that it's not possible isn't simple. And it has to be not possible.

Please sign in to comment.
Something went wrong with that request. Please try again.