From 1cdc511b90eee7351f21359c32c6d13385846dbd Mon Sep 17 00:00:00 2001 From: Timm Date: Fri, 9 Aug 2013 23:18:37 +0200 Subject: Added LinkScrubber to remove duplication in LinkSanitizer. As such made PermitScrubber easier to subclass. --- .../helpers/sanitize_helper/permit_scrubber.rb | 72 ----------------- .../helpers/sanitize_helper/sanitizers.rb | 12 +-- .../helpers/sanitize_helper/scrubbers.rb | 91 ++++++++++++++++++++++ 3 files changed, 93 insertions(+), 82 deletions(-) delete mode 100644 actionview/lib/action_view/helpers/sanitize_helper/permit_scrubber.rb create mode 100644 actionview/lib/action_view/helpers/sanitize_helper/scrubbers.rb diff --git a/actionview/lib/action_view/helpers/sanitize_helper/permit_scrubber.rb b/actionview/lib/action_view/helpers/sanitize_helper/permit_scrubber.rb deleted file mode 100644 index 60c74ed35e..0000000000 --- a/actionview/lib/action_view/helpers/sanitize_helper/permit_scrubber.rb +++ /dev/null @@ -1,72 +0,0 @@ -# === PermitScrubber -# -# PermitScrubber allows you to permit only your own tags and/or attributes. -# -# Supplied tags and attributes should be Enumerables -# -# +tags=+ -# If this value is set all other elements will be stripped (their inner elements will be kept). -# If not set elements for which HTML5::Scrub.allowed_element? is false will be stripped. -# -# +attributes=+ -# Contain an elements allowed attributes. -# If none is set HTML5::Scrub.scrub_attributes implementation will be used. -class PermitScrubber < Loofah::Scrubber - # :nodoc: - attr_reader :tags, :attributes - - def tags=(tags) - @tags = validate!(tags, :tags) - end - - def attributes=(attributes) - @attributes = validate!(attributes, :attributes) - end - - def scrub(node) - return CONTINUE if text_or_cdata_node?(node) - - unless allowed_node?(node) - node.before node.children # strip - node.remove - return STOP - end - - scrub_attributes(node) - end - - protected - - def allowed_node?(node) - if @tags - @tags.include?(node.name) - else - Loofah::HTML5::Scrub.allowed_element?(node.name) - end - end - - def scrub_attributes(node) - if @attributes - node.attributes.each do |name, _| - node.remove_attribute(name) unless @attributes.include?(name) - end - else - Loofah::HTML5::Scrub.scrub_attributes(node) - end - end - - def text_or_cdata_node?(node) - case node.type - when Nokogiri::XML::Node::TEXT_NODE, Nokogiri::XML::Node::CDATA_SECTION_NODE - return true - end - false - end - - def validate!(var, name) - if var && !var.is_a?(Enumerable) - raise ArgumentError, "You should pass :#{name} as an Enumerable" - end - var - end -end diff --git a/actionview/lib/action_view/helpers/sanitize_helper/sanitizers.rb b/actionview/lib/action_view/helpers/sanitize_helper/sanitizers.rb index 3ba46ccaa9..905fa38446 100644 --- a/actionview/lib/action_view/helpers/sanitize_helper/sanitizers.rb +++ b/actionview/lib/action_view/helpers/sanitize_helper/sanitizers.rb @@ -1,6 +1,6 @@ require 'active_support/core_ext/class/attribute' require 'active_support/deprecation' -require 'action_view/helpers/sanitize_helper/permit_scrubber' +require 'action_view/helpers/sanitize_helper/scrubbers' module ActionView XPATHS_TO_REMOVE = %w{.//script .//form comment()} @@ -34,15 +34,7 @@ module ActionView class LinkSanitizer < Sanitizer def initialize - @strip_tags = %w(a href) - @link_scrubber = Loofah::Scrubber.new do |node| - if @strip_tags.include?(node.name) - node.before node.children - node.remove - else - Loofah::HTML5::Scrub.scrub_attributes(node) - end - end + @link_scrubber = LinkScrubber.new end def sanitize(html, options = {}) diff --git a/actionview/lib/action_view/helpers/sanitize_helper/scrubbers.rb b/actionview/lib/action_view/helpers/sanitize_helper/scrubbers.rb new file mode 100644 index 0000000000..2dfe82efab --- /dev/null +++ b/actionview/lib/action_view/helpers/sanitize_helper/scrubbers.rb @@ -0,0 +1,91 @@ +# === PermitScrubber +# +# PermitScrubber allows you to permit only your own tags and/or attributes. +# +# Supplied tags and attributes should be Enumerables +# +# +tags=+ +# If this value is set all other elements will be stripped (their inner elements will be kept). +# If not set elements for which HTML5::Scrub.allowed_element? is false will be stripped. +# +# +attributes=+ +# Contain an elements allowed attributes. +# If none is set HTML5::Scrub.scrub_attributes implementation will be used. +# +# Subclass PermitScrubber to provide your own definition of +# when a node is allowed and how attributes should be scrubbed. +class PermitScrubber < Loofah::Scrubber + # :nodoc: + attr_reader :tags, :attributes + + def tags=(tags) + @tags = validate!(tags, :tags) + end + + def attributes=(attributes) + @attributes = validate!(attributes, :attributes) + end + + def scrub(node) + return CONTINUE if should_skip_node?(node) + + unless allowed_node?(node) + node.before node.children # strip + node.remove + return STOP + end + + scrub_attributes(node) + end + + protected + + def allowed_node?(node) + if @tags + @tags.include?(node.name) + else + Loofah::HTML5::Scrub.allowed_element?(node.name) + end + end + + def scrub_attributes(node) + if @attributes + node.attributes.each do |name, _| + node.remove_attribute(name) unless @attributes.include?(name) + end + else + Loofah::HTML5::Scrub.scrub_attributes(node) + end + end + + def should_skip_node?(node) + text_or_cdata_node?(node) + end + + def text_or_cdata_node?(node) + case node.type + when Nokogiri::XML::Node::TEXT_NODE, Nokogiri::XML::Node::CDATA_SECTION_NODE + return true + end + false + end + + def validate!(var, name) + if var && !var.is_a?(Enumerable) + raise ArgumentError, "You should pass :#{name} as an Enumerable" + end + var + end +end + +# LinkScrubber overrides PermitScrubbers +allowed_node?+ to any nodes +# which names aren't a or href +class LinkScrubber < PermitScrubber + def initialize + @strip_tags = %w(a href) + end + + def allowed_node?(node) + !@strip_tags.include?(node.name) + end +end -- cgit v1.2.3