From 3891c725ade96b7a847ac133496ad307bd05e920 Mon Sep 17 00:00:00 2001 From: Shugo Maeda Date: Thu, 8 Nov 2018 21:02:45 +0900 Subject: sub, sub!, gsub, and gsub! should set back references --- .../core_ext/string/output_safety.rb | 46 +++++++++++++++++++++- 1 file changed, 44 insertions(+), 2 deletions(-) (limited to 'activesupport/lib/active_support/core_ext') 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 3a80de4617..e3f62d7d26 100644 --- a/activesupport/lib/active_support/core_ext/string/output_safety.rb +++ b/activesupport/lib/active_support/core_ext/string/output_safety.rb @@ -135,10 +135,12 @@ module ActiveSupport #:nodoc: class SafeBuffer < String UNSAFE_STRING_METHODS = %w( capitalize chomp chop delete delete_prefix delete_suffix - downcase gsub lstrip next reverse rstrip slice squeeze strip - sub succ swapcase tr tr_s unicode_normalize upcase + downcase lstrip next reverse rstrip slice squeeze strip + succ swapcase tr tr_s unicode_normalize upcase ) + UNSAFE_STRING_METHODS_WITH_BACKREF = %w(gsub sub) + alias_method :original_concat, :concat private :original_concat @@ -249,11 +251,51 @@ module ActiveSupport #:nodoc: end end + UNSAFE_STRING_METHODS_WITH_BACKREF.each do |unsafe_method| + if unsafe_method.respond_to?(unsafe_method) + class_eval <<-EOT, __FILE__, __LINE__ + 1 + def #{unsafe_method}(*args, &block) + if block + to_str.#{unsafe_method}(*args) { |*params| + set_block_back_references(block, $~) + block.call(*params) + } + else + to_str.#{unsafe_method}(*args) + end + end + + def #{unsafe_method}!(*args, &block) + @html_safe = false + if block + super(*args) { |*params| + set_block_back_references(block, $~) + block.call(*params) + } + else + super + end + end + EOT + end + end + private def html_escape_interpolated_argument(arg) (!html_safe? || arg.html_safe?) ? arg : CGI.escapeHTML(arg.to_s) end + + def set_block_back_references(block, match_data) + Thread.current[:__active_support_safe_buffer_backref] = match_data + begin + block.binding.eval(<<-EOC) + $~ = Thread.current[:__active_support_safe_buffer_backref] + EOC + ensure + Thread.current[:__active_support_safe_buffer_backref] = nil + end + end end end -- cgit v1.2.3