File 0004-CVE-2022-27777.patch of Package rubygem-actionview-5_1.30716
diff --git a/actionview/lib/action_view/helpers/tag_helper.rb b/actionview/lib/action_view/helpers/tag_helper.rb
index a6cec3f69c..9f5d90fc85 100644
--- a/actionview/lib/action_view/helpers/tag_helper.rb
+++ b/actionview/lib/action_view/helpers/tag_helper.rb
@@ -41,18 +41,25 @@ def initialize(view_context)
@view_context = view_context
end
- def tag_string(name, content = nil, escape_attributes: true, **options, &block)
+ def tag_string(name, content = nil, **options, &block)
+ escape = handle_deprecated_escape_options(options)
content = @view_context.capture(self, &block) if block_given?
+
if VOID_ELEMENTS.include?(name) && content.nil?
- "<#{name.to_s.dasherize}#{tag_options(options, escape_attributes)}>".html_safe
+ "<#{name.to_s.dasherize}#{tag_options(options, escape)}>".html_safe
else
- content_tag_string(name.to_s.dasherize, content || "", options, escape_attributes)
+ content_tag_string(name.to_s.dasherize, content || "", options, escape)
end
end
def content_tag_string(name, content, options, escape = true)
tag_options = tag_options(options, escape) if options
- content = ERB::Util.unwrapped_html_escape(content) if escape
+
+ if escape
+ name = ERB::Util.xml_name_escape(name)
+ content = ERB::Util.unwrapped_html_escape(content)
+ end
+
"<#{name}#{tag_options}>#{PRE_CONTENT_STRINGS[name]}#{content}</#{name}>".html_safe
end
@@ -85,6 +92,8 @@ def boolean_tag_option(key)
end
def tag_option(key, value, escape)
+ key = ERB::Util.xml_name_escape(key) if escape
+
if value.is_a?(Array)
value = escape ? safe_join(value, " ".freeze) : value.join(" ".freeze)
else
@@ -106,8 +115,29 @@ def respond_to_missing?(*args)
true
end
- def method_missing(called, *args, &block)
- tag_string(called, *args, &block)
+ def handle_deprecated_escape_options(options)
+ # The option :escape_attributes has been merged into the options hash to be
+ # able to warn when it is used, so we need to handle default values here.
+ escape_option_provided = options.has_key?(:escape)
+ escape_attributes_option_provided = options.has_key?(:escape_attributes)
+
+ if escape_attributes_option_provided
+ ActiveSupport::Deprecation.warn(<<~MSG)
+ Use of the option :escape_attributes is deprecated. It currently \
+ escapes both names and values of tags and attributes and it is \
+ equivalent to :escape. If any of them are enabled, the escaping \
+ is fully enabled.
+ MSG
+ end
+
+ return true unless escape_option_provided || escape_attributes_option_provided
+ escape_option = options.delete(:escape)
+ escape_attributes_option = options.delete(:escape_attributes)
+ escape_option || escape_attributes_option
+ end
+
+ def method_missing(called, *args, **options, &block)
+ tag_string(called, *args, **options, &block)
end
end
@@ -236,6 +266,7 @@ def tag(name = nil, options = nil, open = false, escape = true)
if name.nil?
tag_builder
else
+ name = ERB::Util.xml_name_escape(name) if escape
"<#{name}#{tag_builder.tag_options(options, escape) if options}#{open ? ">" : " />"}".html_safe
end
end
--
2.36.0