Skip to content

Commit a2edfdc

Browse files
committed
Do not scrub attributes on a removed node
This should improve performance by eliminating unneeded scrubbing of attributes.
1 parent c5734e5 commit a2edfdc

File tree

2 files changed

+48
-3
lines changed

2 files changed

+48
-3
lines changed

lib/rails/html/scrubbers.rb

+2-1
Original file line numberDiff line numberDiff line change
@@ -72,10 +72,11 @@ def scrub(node)
7272
return CONTINUE if skip_node?(node)
7373

7474
unless (node.element? || node.comment?) && keep_node?(node)
75-
return STOP if scrub_node(node) == STOP
75+
return STOP unless scrub_node(node) == CONTINUE
7676
end
7777

7878
scrub_attributes(node)
79+
CONTINUE
7980
end
8081

8182
protected

test/scrubbers_test.rb

+46-2
Original file line numberDiff line numberDiff line change
@@ -207,11 +207,55 @@ def scrub_node(node)
207207
end
208208
end
209209

210-
def setup
211-
@scrubber = ScrubStopper.new
210+
class ScrubContinuer < Rails::HTML::PermitScrubber
211+
def scrub_node(node)
212+
Loofah::Scrubber::CONTINUE
213+
end
212214
end
213215

214216
def test_returns_stop_from_scrub_if_scrub_node_does
217+
@scrubber = ScrubStopper.new
215218
assert_scrub_stopped "<script>remove me</script>"
216219
end
220+
221+
def test_returns_continue_from_scrub_if_scrub_node_does
222+
@scrubber = ScrubContinuer.new
223+
assert_node_skipped "<script>keep me</script>"
224+
end
225+
end
226+
227+
class PermitScrubberMinimalOperationsTest < ScrubberTest
228+
class TestPermitScrubber < Rails::HTML::PermitScrubber
229+
def initialize
230+
@scrub_attribute_args = []
231+
@scrub_attributes_args = []
232+
233+
super
234+
235+
self.tags = ["div"]
236+
self.attributes = ["class"]
237+
end
238+
239+
def scrub_attributes(node)
240+
@scrub_attributes_args << node.name
241+
242+
super
243+
end
244+
245+
def scrub_attribute(node, attr)
246+
@scrub_attribute_args << [node.name, attr.name]
247+
248+
super
249+
end
250+
end
251+
252+
def test_does_not_scrub_attributes_of_a_removed_node
253+
@scrubber = TestPermitScrubber.new
254+
255+
input = "<div class='foo' href='bar'><svg xlink:href='asdf'><set></set></svg></div>"
256+
frag = scrub_fragment(input)
257+
assert_equal("<div class=\"foo\"></div>", frag)
258+
259+
assert_equal(["div"], @scrubber.instance_variable_get(:@scrub_attributes_args))
260+
end
217261
end

0 commit comments

Comments
 (0)