aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport/lib/active_support/core_ext/string
diff options
context:
space:
mode:
Diffstat (limited to 'activesupport/lib/active_support/core_ext/string')
-rw-r--r--activesupport/lib/active_support/core_ext/string/output_safety.rb53
1 files changed, 39 insertions, 14 deletions
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 20e40fe40f..a19b5c95c7 100644
--- a/activesupport/lib/active_support/core_ext/string/output_safety.rb
+++ b/activesupport/lib/active_support/core_ext/string/output_safety.rb
@@ -76,10 +76,33 @@ 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
- alias safe_concat concat
+
+ alias_method :original_concat, :concat
+ private :original_concat
+
+ class SafeConcatError < StandardError
+ def initialize
+ super "Could not concatenate to the buffer because it is not html safe."
+ end
+ end
+
+ def safe_concat(value)
+ raise SafeConcatError if dirty?
+ original_concat(value)
+ end
+
+ 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,15 +115,15 @@ module ActiveSupport #:nodoc:
end
def html_safe?
- true
+ !dirty?
end
- def html_safe
+ def to_s
self
end
- def to_s
- self
+ def to_param
+ to_str
end
def encode_with(coder)
@@ -109,29 +132,31 @@ module ActiveSupport #:nodoc:
def to_yaml(*args)
return super() if defined?(YAML::ENGINE) && !YAML::ENGINE.syck?
-
to_str.to_yaml(*args)
end
UNSAFE_STRING_METHODS.each do |unsafe_method|
class_eval <<-EOT, __FILE__, __LINE__
- def #{unsafe_method}(*args)
- super.to_str
+ def #{unsafe_method}(*args, &block)
+ to_str.#{unsafe_method}(*args, &block)
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