Reputation: 137
I’ve been stuck trying to figure out how to use the Rails sanitizer. It doesn’t seem to be working as I expected. Think I’m misunderstanding something.
Basically, I'm trying to sanitize all divs
except divs
that have an attribute that have a value of highlight
. But for example's sake, I tried to use PermitScrubber
on it's own.
I set my tags and attributes and am inheriting from PermitScrubber, but it scrubs my permitted tags and attributes anyway:
class ExampleScrubber < Rails::Html::PermitScrubber
def initialize
super
self.tags = %w(img),
self.attributes = %w(src alt)
end
# commented out for the example, but what I'm trying to ultimately do
# def allowed_node?(node)
# node.name == "div" && node.attributes.values.first.value = "highlight"
# end
end
@comment.body = "<ul>\n<li>yes</li>\n<li>tests</li>\n</ul>\n\n<p><img src=\"something.jpeg\" alt=\"something\"></p>\n"
ActionController::Base.helpers.sanitize(
@comment.body,
scrubber: ExampleScrubber.new
)
#=> "\nyes\ntests\n\n\n\n"
So two things:
1. Why is scrubbing the img
tag and src
and alt
attributes?
2. I know I could refactor the allowed_node?
method, but I want to figure out number one first.
Thanks for reading ✌️
Upvotes: 0
Views: 722
Reputation: 11035
The first problem ("Why is [this] scrubbing the img
tag and src
and alt
attributes?") is caused by the stray comma after the array.
# Here v
self.tags = %w(img),
TIL Ruby doesn't require the square brackets for arrays:
a = "b", "c" # => ["b", "c"]
So, that comma is turning your tags
into an array of arrays:
ExampleScrubber.new.tags # => [["img"], ["src", "alt"]]
Which is causing issues and allowing the tag to be scrubbed. Removing the comma causes things to work correctly:
class ExampleScrubber < Rails::Html::PermitScrubber
def initialize
super
self.tags = %w(img)
self.attributes = %w(src alt)
end
# commented out for the example, but what I'm trying to ultimately do
# def allowed_node?(node)
# node.name == "div" && node.attributes.values.first.value = "highlight"
# end
end
body = "<ul>\n<li>yes</li>\n<li>tests</li>\n</ul>\n\n<p><img src=\"something.jpeg\" alt=\"something\"></p>\n"
ActionController::Base.helpers.sanitize(body, scrubber: ExampleScrubber.new)
# => "\nyes\ntests\n\n\n<img src=\"something.jpeg\" alt=\"something\">\n"
So to accomplish your goal, to only keep divs
and only if they have an attribute (any attribute) including the word 'highlight' you might try something like:
class ExampleScrubber < Rails::Html::PermitScrubber
def initialize
super
self.tags = %w( div )
end
def allowed_node?(node)
@tags.include?(node.name) && node.attributes.values.any? do |attribute_value|
attribute_value.value.include?('highlight')
end
end
end
body = "<ul>\n<li class='highlight'>yes</li>\n<li>tests</li>\n</ul>\n\n<p><img src=\"something.jpeg\" alt=\"something\"></p>\n<div class='highlight'>Something</div><div>Else</div>"
results = ActionController::Base.helpers.sanitize(body, scrubber: ExampleScrubber.new)
# => "\nyes\ntests\n\n\n\n<div class=\"highlight\">Something</div>Else"
Upvotes: 2