loofah 0.4.4 → 0.4.5
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of loofah might be problematic. Click here for more details.
- data.tar.gz.sig +0 -0
- data/Manifest.txt +9 -7
- data/lib/loofah.rb +1 -1
- data/lib/loofah/html/document.rb +3 -2
- data/lib/loofah/html/document_fragment.rb +1 -3
- data/lib/loofah/xml/document_fragment.rb +0 -2
- data/test/{test_ad_hoc.rb → integration/test_ad_hoc.rb} +77 -97
- data/test/integration/test_helpers.rb +33 -0
- data/test/integration/test_scrubbers.rb +294 -0
- data/test/{test_active_record.rb → unit/test_active_record.rb} +7 -10
- data/test/{test_api.rb → unit/test_api.rb} +1 -1
- data/test/{test_helpers.rb → unit/test_helpers.rb} +4 -5
- data/test/{test_scrubber.rb → unit/test_scrubber.rb} +3 -1
- data/test/unit/test_scrubbers.rb +14 -0
- data/test/{test_xss_foliate.rb → unit/test_xss_foliate.rb} +22 -22
- metadata +20 -16
- metadata.gz.sig +0 -0
- data/test/test_scrubbers.rb +0 -144
data.tar.gz.sig
CHANGED
Binary file
|
data/Manifest.txt
CHANGED
@@ -25,10 +25,12 @@ lib/loofah/xml/document_fragment.rb
|
|
25
25
|
lib/loofah/xss_foliate.rb
|
26
26
|
test/helper.rb
|
27
27
|
test/html5/test_sanitizer.rb
|
28
|
-
test/
|
29
|
-
test/
|
30
|
-
test/
|
31
|
-
test/
|
32
|
-
test/
|
33
|
-
test/
|
34
|
-
test/
|
28
|
+
test/integration/test_ad_hoc.rb
|
29
|
+
test/integration/test_helpers.rb
|
30
|
+
test/integration/test_scrubbers.rb
|
31
|
+
test/unit/test_active_record.rb
|
32
|
+
test/unit/test_api.rb
|
33
|
+
test/unit/test_helpers.rb
|
34
|
+
test/unit/test_scrubber.rb
|
35
|
+
test/unit/test_scrubbers.rb
|
36
|
+
test/unit/test_xss_foliate.rb
|
data/lib/loofah.rb
CHANGED
data/lib/loofah/html/document.rb
CHANGED
@@ -10,10 +10,11 @@ module Loofah
|
|
10
10
|
include Loofah::DocumentDecorator
|
11
11
|
|
12
12
|
#
|
13
|
-
# Returns a plain-text version of the markup contained by the document
|
13
|
+
# Returns a plain-text version of the markup contained by the document,
|
14
|
+
# with HTML entities encoded.
|
14
15
|
#
|
15
16
|
def text
|
16
|
-
xpath("/html/body").inner_text
|
17
|
+
encode_special_chars xpath("/html/body").inner_text
|
17
18
|
end
|
18
19
|
alias :inner_text :text
|
19
20
|
alias :to_str :text
|
@@ -6,8 +6,6 @@ module Loofah
|
|
6
6
|
# See Loofah::ScrubBehavior for additional methods.
|
7
7
|
#
|
8
8
|
class DocumentFragment < Nokogiri::HTML::DocumentFragment
|
9
|
-
include Loofah::ScrubBehavior::Node
|
10
|
-
|
11
9
|
class << self
|
12
10
|
#
|
13
11
|
# Overridden Nokogiri::HTML::DocumentFragment
|
@@ -31,7 +29,7 @@ module Loofah
|
|
31
29
|
# Returns a plain-text version of the markup contained by the fragment
|
32
30
|
#
|
33
31
|
def text
|
34
|
-
serialize_roots.children.inner_text
|
32
|
+
encode_special_chars serialize_roots.children.inner_text
|
35
33
|
end
|
36
34
|
alias :inner_text :text
|
37
35
|
alias :to_str :text
|
@@ -1,109 +1,94 @@
|
|
1
|
-
require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'helper'))
|
2
2
|
|
3
3
|
class TestAdHoc < Test::Unit::TestCase
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
def test_empty_string_with_prune
|
10
|
-
assert_equal Loofah.scrub_document("", :prune).text, ""
|
11
|
-
end
|
12
|
-
|
13
|
-
def test_xml_document_scrub
|
14
|
-
xml = Loofah.xml_document <<-EOXML
|
15
|
-
<root>
|
16
|
-
<employee deceased='true'>Abraham Lincoln</employee>
|
17
|
-
<employee deceased='false'>Abe Vigoda</employee>
|
18
|
-
</root>
|
19
|
-
EOXML
|
20
|
-
bring_out_your_dead = Loofah::Scrubber.new do |node|
|
21
|
-
if node.name == "employee" and node["deceased"] == "true"
|
22
|
-
node.remove
|
23
|
-
Loofah::Scrubber::STOP # don't bother with the rest of the subtree
|
5
|
+
context "blank input string" do
|
6
|
+
context "fragment" do
|
7
|
+
should "return a blank string" do
|
8
|
+
assert_equal "", Loofah.scrub_fragment("", :prune).to_s
|
24
9
|
end
|
25
10
|
end
|
26
|
-
assert_equal 2, xml.css("employee").length
|
27
|
-
|
28
|
-
xml.scrub!(bring_out_your_dead)
|
29
|
-
|
30
|
-
employees = xml.css "employee"
|
31
|
-
assert_equal 1, employees.length
|
32
|
-
assert_equal "Abe Vigoda", employees.first.inner_text
|
33
|
-
end
|
34
11
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
<employee deceased='false'>Abe Vigoda</employee>
|
39
|
-
EOXML
|
40
|
-
bring_out_your_dead = Loofah::Scrubber.new do |node|
|
41
|
-
if node.name == "employee" and node["deceased"] == "true"
|
42
|
-
node.remove
|
43
|
-
Loofah::Scrubber::STOP # don't bother with the rest of the subtree
|
12
|
+
context "document" do
|
13
|
+
should "return a blank string" do
|
14
|
+
assert_equal "", Loofah.scrub_document("", :prune).root.to_s
|
44
15
|
end
|
45
16
|
end
|
46
|
-
assert_equal 2, xml.css("employee").length
|
47
|
-
|
48
|
-
xml.scrub!(bring_out_your_dead)
|
49
|
-
|
50
|
-
employees = xml.css "employee"
|
51
|
-
assert_equal 1, employees.length
|
52
|
-
assert_equal "Abe Vigoda", employees.first.inner_text
|
53
17
|
end
|
54
18
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
19
|
+
context "integration test" do
|
20
|
+
context "xml document" do
|
21
|
+
context "custom scrubber" do
|
22
|
+
should "act as expected" do
|
23
|
+
xml = Loofah.xml_document <<-EOXML
|
24
|
+
<root>
|
25
|
+
<employee deceased='true'>Abraham Lincoln</employee>
|
26
|
+
<employee deceased='false'>Abe Vigoda</employee>
|
27
|
+
</root>
|
28
|
+
EOXML
|
29
|
+
bring_out_your_dead = Loofah::Scrubber.new do |node|
|
30
|
+
if node.name == "employee" and node["deceased"] == "true"
|
31
|
+
node.remove
|
32
|
+
Loofah::Scrubber::STOP # don't bother with the rest of the subtree
|
33
|
+
end
|
34
|
+
end
|
35
|
+
assert_equal 2, xml.css("employee").length
|
36
|
+
|
37
|
+
xml.scrub!(bring_out_your_dead)
|
38
|
+
|
39
|
+
employees = xml.css "employee"
|
40
|
+
assert_equal 1, employees.length
|
41
|
+
assert_equal "Abe Vigoda", employees.first.inner_text
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
59
45
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
46
|
+
context "xml fragment" do
|
47
|
+
context "custom scrubber" do
|
48
|
+
should "act as expected" do
|
49
|
+
xml = Loofah.xml_fragment <<-EOXML
|
50
|
+
<employee deceased='true'>Abraham Lincoln</employee>
|
51
|
+
<employee deceased='false'>Abe Vigoda</employee>
|
52
|
+
EOXML
|
53
|
+
bring_out_your_dead = Loofah::Scrubber.new do |node|
|
54
|
+
if node.name == "employee" and node["deceased"] == "true"
|
55
|
+
node.remove
|
56
|
+
Loofah::Scrubber::STOP # don't bother with the rest of the subtree
|
57
|
+
end
|
58
|
+
end
|
59
|
+
assert_equal 2, xml.css("employee").length
|
60
|
+
|
61
|
+
xml.scrub!(bring_out_your_dead)
|
62
|
+
|
63
|
+
employees = xml.css "employee"
|
64
|
+
assert_equal 1, employees.length
|
65
|
+
assert_equal "Abe Vigoda", employees.first.inner_text
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
64
69
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
70
|
+
context "html fragment" do
|
71
|
+
context "#to_s" do
|
72
|
+
should "not include head tags (like style)" do
|
73
|
+
html = Loofah.fragment "<style>foo</style><div>bar</div>"
|
74
|
+
assert_equal "<div>bar</div>", html.to_s
|
75
|
+
end
|
76
|
+
end
|
69
77
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
<script>I should remain</script>
|
78
|
-
</div>
|
79
|
-
</body></html>
|
80
|
-
EOHTML
|
81
|
-
node = xml.at_css "div.scrub"
|
82
|
-
node.scrub!(:prune)
|
83
|
-
assert_contains xml.to_s, /I should remain/
|
84
|
-
assert_does_not_contain xml.to_s, /I should be removed/
|
85
|
-
end
|
78
|
+
context "#text" do
|
79
|
+
should "not include head tags (like style)" do
|
80
|
+
html = Loofah.fragment "<style>foo</style><div>bar</div>"
|
81
|
+
assert_equal "bar", html.text
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
86
85
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
<div class='noscrub'>
|
94
|
-
<script>I should remain</script>
|
95
|
-
</div>
|
96
|
-
<div class='scrub'>
|
97
|
-
<script>I should also be removed</script>
|
98
|
-
</div>
|
99
|
-
</body></html>
|
100
|
-
EOHTML
|
101
|
-
node_set = xml.css "div.scrub"
|
102
|
-
assert_equal 2, node_set.length
|
103
|
-
node_set.scrub!(:prune)
|
104
|
-
assert_contains xml.to_s, /I should remain/
|
105
|
-
assert_does_not_contain xml.to_s, /I should be removed/
|
106
|
-
assert_does_not_contain xml.to_s, /I should also be removed/
|
86
|
+
context "html document" do
|
87
|
+
should "not include head tags (like style)" do
|
88
|
+
html = Loofah.document "<style>foo</style><div>bar</div>"
|
89
|
+
assert_equal "bar", html.text
|
90
|
+
end
|
91
|
+
end
|
107
92
|
end
|
108
93
|
|
109
94
|
def test_removal_of_illegal_tag
|
@@ -263,9 +248,4 @@ mso-bidi-language:#0400;}
|
|
263
248
|
html = "<p>Foo</p>\n<p>Bar</p>"
|
264
249
|
assert_equal "Foo\nBar", Loofah.scrub_document(html, :prune).text
|
265
250
|
end
|
266
|
-
|
267
|
-
def test_removal_of_entities
|
268
|
-
html = "<p>this is < that "&" the other > boo'ya</p>"
|
269
|
-
assert_equal 'this is < that "&" the other > boo\'ya', Loofah.scrub_document(html, :prune).text
|
270
|
-
end
|
271
251
|
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'helper'))
|
2
|
+
|
3
|
+
class TestHelpers < Test::Unit::TestCase
|
4
|
+
context "#strip_tags" do
|
5
|
+
context "on safe markup" do
|
6
|
+
should "strip out tags" do
|
7
|
+
assert_equal "omgwtfbbq!!1!", Loofah::Helpers.strip_tags("<div>omgwtfbbq</div><span>!!1!</span>")
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
context "on hack attack" do
|
12
|
+
should "strip escape html entities" do
|
13
|
+
bad_shit = "<script>alert('evil')</script>"
|
14
|
+
assert_equal bad_shit, Loofah::Helpers.strip_tags(bad_shit)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
context "#sanitize" do
|
20
|
+
context "on safe markup" do
|
21
|
+
should "render the safe html" do
|
22
|
+
html = "<div>omgwtfbbq</div><span>!!1!</span>"
|
23
|
+
assert_equal html, Loofah::Helpers.sanitize(html)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context "on hack attack" do
|
28
|
+
should "strip the unsafe tags" do
|
29
|
+
assert_equal "alert('evil')<span>w00t</span>", Loofah::Helpers.sanitize("<script>alert('evil')</script><span>w00t</span>")
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,294 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'helper'))
|
2
|
+
|
3
|
+
class TestScrubbers < Test::Unit::TestCase
|
4
|
+
|
5
|
+
INVALID_FRAGMENT = "<invalid>foo<p>bar</p>bazz</invalid><div>quux</div>"
|
6
|
+
INVALID_ESCAPED = "<invalid>foo<p>bar</p>bazz</invalid><div>quux</div>"
|
7
|
+
INVALID_PRUNED = "<div>quux</div>"
|
8
|
+
INVALID_STRIPPED = "foo<p>bar</p>bazz<div>quux</div>"
|
9
|
+
|
10
|
+
WHITEWASH_FRAGMENT = "<o:div>no</o:div><div id='no'>foo</div><invalid>bar</invalid>"
|
11
|
+
WHITEWASH_RESULT = "<div>foo</div>"
|
12
|
+
|
13
|
+
NOFOLLOW_FRAGMENT = '<a href="http://www.example.com/">Click here</a>'
|
14
|
+
NOFOLLOW_RESULT = '<a href="http://www.example.com/" rel="nofollow">Click here</a>'
|
15
|
+
|
16
|
+
ENTITY_FRAGMENT = "<p>this is < that "&" the other > boo'ya</p><div>w00t</div>"
|
17
|
+
ENTITY_TEXT = %Q(this is < that "&" the other > boo\'yaw00t)
|
18
|
+
|
19
|
+
ENTITY_HACK_ATTACK = "<div><div>Hack attack!</div><div><script>alert('evil')</script></div></div>"
|
20
|
+
ENTITY_HACK_ATTACK_TEXT_SCRUB = "Hack attack!<script>alert('evil')</script>"
|
21
|
+
|
22
|
+
context "Document" do
|
23
|
+
context "#scrub!" do
|
24
|
+
context ":escape" do
|
25
|
+
should "escape bad tags" do
|
26
|
+
doc = Loofah::HTML::Document.parse "<html><body>#{INVALID_FRAGMENT}</body></html>"
|
27
|
+
result = doc.scrub! :escape
|
28
|
+
|
29
|
+
assert_equal INVALID_ESCAPED, doc.xpath('/html/body').inner_html
|
30
|
+
assert_equal doc, result
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context ":prune" do
|
35
|
+
should "prune bad tags" do
|
36
|
+
doc = Loofah::HTML::Document.parse "<html><body>#{INVALID_FRAGMENT}</body></html>"
|
37
|
+
result = doc.scrub! :prune
|
38
|
+
|
39
|
+
assert_equal INVALID_PRUNED, doc.xpath('/html/body').inner_html
|
40
|
+
assert_equal doc, result
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
context ":strip" do
|
45
|
+
should "strip bad tags" do
|
46
|
+
doc = Loofah::HTML::Document.parse "<html><body>#{INVALID_FRAGMENT}</body></html>"
|
47
|
+
result = doc.scrub! :strip
|
48
|
+
|
49
|
+
assert_equal INVALID_STRIPPED, doc.xpath('/html/body').inner_html
|
50
|
+
assert_equal doc, result
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context ":whitewash" do
|
55
|
+
should "whitewash the markup" do
|
56
|
+
doc = Loofah::HTML::Document.parse "<html><body>#{WHITEWASH_FRAGMENT}</body></html>"
|
57
|
+
result = doc.scrub! :whitewash
|
58
|
+
|
59
|
+
assert_equal WHITEWASH_RESULT, doc.xpath('/html/body').inner_html
|
60
|
+
assert_equal doc, result
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
context ":nofollow" do
|
65
|
+
should "add a 'nofollow' attribute to hyperlinks" do
|
66
|
+
doc = Loofah::HTML::Document.parse "<html><body>#{NOFOLLOW_FRAGMENT}</body></html>"
|
67
|
+
result = doc.scrub! :nofollow
|
68
|
+
|
69
|
+
assert_equal NOFOLLOW_RESULT, doc.xpath('/html/body').inner_html
|
70
|
+
assert_equal doc, result
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
context "#scrub_document" do
|
76
|
+
should "be a shortcut for parse-and-scrub" do
|
77
|
+
mock_doc = mock
|
78
|
+
Loofah.expects(:document).with(:string_or_io).returns(mock_doc)
|
79
|
+
mock_doc.expects(:scrub!).with(:method)
|
80
|
+
|
81
|
+
Loofah.scrub_document(:string_or_io, :method)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
context "#text" do
|
86
|
+
should "leave behind only inner text with html entities still escaped" do
|
87
|
+
doc = Loofah::HTML::Document.parse "<html><body>#{ENTITY_HACK_ATTACK}</body></html>"
|
88
|
+
result = doc.text
|
89
|
+
|
90
|
+
assert_equal ENTITY_HACK_ATTACK_TEXT_SCRUB, result
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
context "#to_s" do
|
95
|
+
should "generate HTML" do
|
96
|
+
doc = Loofah.scrub_document "<html><head><title>quux</title></head><body><div>foo</div></body></html>", :prune
|
97
|
+
assert_not_nil doc.xpath("/html").first
|
98
|
+
assert_not_nil doc.xpath("/html/head").first
|
99
|
+
assert_not_nil doc.xpath("/html/body").first
|
100
|
+
|
101
|
+
string = doc.to_s
|
102
|
+
assert_contains string, /<!DOCTYPE/
|
103
|
+
assert_contains string, /<html>/
|
104
|
+
assert_contains string, /<head>/
|
105
|
+
assert_contains string, /<body>/
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
context "#serialize" do
|
110
|
+
should "generate HTML" do
|
111
|
+
doc = Loofah.scrub_document "<html><head><title>quux</title></head><body><div>foo</div></body></html>", :prune
|
112
|
+
assert_not_nil doc.xpath("/html").first
|
113
|
+
assert_not_nil doc.xpath("/html/head").first
|
114
|
+
assert_not_nil doc.xpath("/html/body").first
|
115
|
+
|
116
|
+
string = doc.serialize
|
117
|
+
assert_contains string, /<!DOCTYPE/
|
118
|
+
assert_contains string, /<html>/
|
119
|
+
assert_contains string, /<head>/
|
120
|
+
assert_contains string, /<body>/
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
context "Node" do
|
125
|
+
context "#scrub!" do
|
126
|
+
should "only scrub subtree" do
|
127
|
+
xml = Loofah.document <<-EOHTML
|
128
|
+
<html><body>
|
129
|
+
<div class='scrub'>
|
130
|
+
<script>I should be removed</script>
|
131
|
+
</div>
|
132
|
+
<div class='noscrub'>
|
133
|
+
<script>I should remain</script>
|
134
|
+
</div>
|
135
|
+
</body></html>
|
136
|
+
EOHTML
|
137
|
+
node = xml.at_css "div.scrub"
|
138
|
+
node.scrub!(:prune)
|
139
|
+
assert_contains xml.to_s, /I should remain/
|
140
|
+
assert_does_not_contain xml.to_s, /I should be removed/
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
context "NodeSet" do
|
146
|
+
context "#scrub!" do
|
147
|
+
should "only scrub subtrees" do
|
148
|
+
xml = Loofah.document <<-EOHTML
|
149
|
+
<html><body>
|
150
|
+
<div class='scrub'>
|
151
|
+
<script>I should be removed</script>
|
152
|
+
</div>
|
153
|
+
<div class='noscrub'>
|
154
|
+
<script>I should remain</script>
|
155
|
+
</div>
|
156
|
+
<div class='scrub'>
|
157
|
+
<script>I should also be removed</script>
|
158
|
+
</div>
|
159
|
+
</body></html>
|
160
|
+
EOHTML
|
161
|
+
node_set = xml.css "div.scrub"
|
162
|
+
assert_equal 2, node_set.length
|
163
|
+
node_set.scrub!(:prune)
|
164
|
+
assert_contains xml.to_s, /I should remain/
|
165
|
+
assert_does_not_contain xml.to_s, /I should be removed/
|
166
|
+
assert_does_not_contain xml.to_s, /I should also be removed/
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
context "DocumentFragment" do
|
173
|
+
context "#scrub!" do
|
174
|
+
context ":escape" do
|
175
|
+
should "escape bad tags" do
|
176
|
+
doc = Loofah::HTML::DocumentFragment.parse "<div>#{INVALID_FRAGMENT}</div>"
|
177
|
+
result = doc.scrub! :escape
|
178
|
+
|
179
|
+
assert_equal INVALID_ESCAPED, doc.xpath("./div").inner_html
|
180
|
+
assert_equal doc, result
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
context ":prune" do
|
185
|
+
should "prune bad tags" do
|
186
|
+
doc = Loofah::HTML::DocumentFragment.parse "<div>#{INVALID_FRAGMENT}</div>"
|
187
|
+
result = doc.scrub! :prune
|
188
|
+
|
189
|
+
assert_equal INVALID_PRUNED, doc.xpath("./div").inner_html
|
190
|
+
assert_equal doc, result
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
context ":strip" do
|
195
|
+
should "strip bad tags" do
|
196
|
+
doc = Loofah::HTML::DocumentFragment.parse "<div>#{INVALID_FRAGMENT}</div>"
|
197
|
+
result = doc.scrub! :strip
|
198
|
+
|
199
|
+
assert_equal INVALID_STRIPPED, doc.xpath("./div").inner_html
|
200
|
+
assert_equal doc, result
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
context ":whitewash" do
|
205
|
+
should "whitewash the markup" do
|
206
|
+
doc = Loofah::HTML::DocumentFragment.parse "<div>#{WHITEWASH_FRAGMENT}</div>"
|
207
|
+
result = doc.scrub! :whitewash
|
208
|
+
|
209
|
+
assert_equal WHITEWASH_RESULT, doc.xpath("./div").inner_html
|
210
|
+
assert_equal doc, result
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
context ":nofollow" do
|
215
|
+
should "add a 'nofollow' attribute to hyperlinks" do
|
216
|
+
doc = Loofah::HTML::DocumentFragment.parse "<div>#{NOFOLLOW_FRAGMENT}</div>"
|
217
|
+
result = doc.scrub! :nofollow
|
218
|
+
|
219
|
+
assert_equal NOFOLLOW_RESULT, doc.xpath("./div").inner_html
|
220
|
+
assert_equal doc, result
|
221
|
+
end
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
context "#scrub_fragment" do
|
226
|
+
should "be a shortcut for parse-and-scrub" do
|
227
|
+
mock_doc = mock
|
228
|
+
Loofah.expects(:fragment).with(:string_or_io).returns(mock_doc)
|
229
|
+
mock_doc.expects(:scrub!).with(:method)
|
230
|
+
|
231
|
+
Loofah.scrub_fragment(:string_or_io, :method)
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
context "#text" do
|
236
|
+
should "leave behind only inner text with html entities still escaped" do
|
237
|
+
doc = Loofah::HTML::DocumentFragment.parse "<div>#{ENTITY_HACK_ATTACK}</div>"
|
238
|
+
result = doc.text
|
239
|
+
|
240
|
+
assert_equal ENTITY_HACK_ATTACK_TEXT_SCRUB, result
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
context "#to_s" do
|
245
|
+
should "not remove entities" do
|
246
|
+
string = Loofah.scrub_fragment(ENTITY_FRAGMENT, :prune).to_s
|
247
|
+
assert_contains string, /this is </
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
context "Node" do
|
252
|
+
context "#scrub!" do
|
253
|
+
should "only scrub subtree" do
|
254
|
+
xml = Loofah.fragment <<-EOHTML
|
255
|
+
<div class='scrub'>
|
256
|
+
<script>I should be removed</script>
|
257
|
+
</div>
|
258
|
+
<div class='noscrub'>
|
259
|
+
<script>I should remain</script>
|
260
|
+
</div>
|
261
|
+
EOHTML
|
262
|
+
node = xml.at_css "div.scrub"
|
263
|
+
node.scrub!(:prune)
|
264
|
+
assert_contains xml.to_s, /I should remain/
|
265
|
+
assert_does_not_contain xml.to_s, /I should be removed/
|
266
|
+
end
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
270
|
+
context "NodeSet" do
|
271
|
+
context "#scrub!" do
|
272
|
+
should "only scrub subtrees" do
|
273
|
+
xml = Loofah.fragment <<-EOHTML
|
274
|
+
<div class='scrub'>
|
275
|
+
<script>I should be removed</script>
|
276
|
+
</div>
|
277
|
+
<div class='noscrub'>
|
278
|
+
<script>I should remain</script>
|
279
|
+
</div>
|
280
|
+
<div class='scrub'>
|
281
|
+
<script>I should also be removed</script>
|
282
|
+
</div>
|
283
|
+
EOHTML
|
284
|
+
node_set = xml.css "div.scrub"
|
285
|
+
assert_equal 2, node_set.length
|
286
|
+
node_set.scrub!(:prune)
|
287
|
+
assert_contains xml.to_s, /I should remain/
|
288
|
+
assert_does_not_contain xml.to_s, /I should be removed/
|
289
|
+
assert_does_not_contain xml.to_s, /I should also be removed/
|
290
|
+
end
|
291
|
+
end
|
292
|
+
end
|
293
|
+
end
|
294
|
+
end
|
@@ -1,14 +1,13 @@
|
|
1
|
-
require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'helper'))
|
2
2
|
|
3
3
|
require 'loofah/active_record'
|
4
4
|
|
5
5
|
class TestActiveRecord < Test::Unit::TestCase
|
6
6
|
|
7
7
|
HTML_STRING = "<div>omgwtfbbq</div>"
|
8
|
-
PLAIN_TEXT
|
8
|
+
PLAIN_TEXT = "vanilla text"
|
9
9
|
|
10
10
|
context "with a Post model" do
|
11
|
-
|
12
11
|
setup do
|
13
12
|
ActsAsFu.build_model(:posts) do
|
14
13
|
string :plain_text
|
@@ -26,7 +25,7 @@ class TestActiveRecord < Test::Unit::TestCase
|
|
26
25
|
|
27
26
|
should "scrub the specified field" do
|
28
27
|
Loofah.expects(:scrub_fragment).with(HTML_STRING, :prune).once
|
29
|
-
Loofah.expects(:scrub_fragment).with(PLAIN_TEXT,
|
28
|
+
Loofah.expects(:scrub_fragment).with(PLAIN_TEXT, :prune).never
|
30
29
|
@post.valid?
|
31
30
|
end
|
32
31
|
|
@@ -37,7 +36,7 @@ class TestActiveRecord < Test::Unit::TestCase
|
|
37
36
|
|
38
37
|
should "generate strings" do
|
39
38
|
@post.valid?
|
40
|
-
assert_equal String,
|
39
|
+
assert_equal String, @post.html_string.class
|
41
40
|
assert_equal HTML_STRING, @post.html_string
|
42
41
|
end
|
43
42
|
end
|
@@ -51,7 +50,7 @@ class TestActiveRecord < Test::Unit::TestCase
|
|
51
50
|
|
52
51
|
should "scrub the specified field" do
|
53
52
|
Loofah.expects(:scrub_fragment).with(HTML_STRING, :prune).once
|
54
|
-
Loofah.expects(:scrub_fragment).with(PLAIN_TEXT,
|
53
|
+
Loofah.expects(:scrub_fragment).with(PLAIN_TEXT, :prune).never
|
55
54
|
@post.valid?
|
56
55
|
end
|
57
56
|
end
|
@@ -66,7 +65,7 @@ class TestActiveRecord < Test::Unit::TestCase
|
|
66
65
|
|
67
66
|
should "scrub the specified field, but not other fields" do
|
68
67
|
Loofah.expects(:scrub_document).with(HTML_STRING, :strip).once
|
69
|
-
Loofah.expects(:scrub_document).with(PLAIN_TEXT,
|
68
|
+
Loofah.expects(:scrub_document).with(PLAIN_TEXT, :strip).never
|
70
69
|
@post.valid?
|
71
70
|
end
|
72
71
|
|
@@ -89,7 +88,7 @@ class TestActiveRecord < Test::Unit::TestCase
|
|
89
88
|
|
90
89
|
should "scrub the specified field, but not other fields" do
|
91
90
|
Loofah.expects(:scrub_document).with(HTML_STRING, :strip).once
|
92
|
-
Loofah.expects(:scrub_document).with(PLAIN_TEXT,
|
91
|
+
Loofah.expects(:scrub_document).with(PLAIN_TEXT, :strip).never
|
93
92
|
@post.valid?
|
94
93
|
end
|
95
94
|
end
|
@@ -140,7 +139,5 @@ class TestActiveRecord < Test::Unit::TestCase
|
|
140
139
|
assert @called
|
141
140
|
end
|
142
141
|
end
|
143
|
-
|
144
142
|
end
|
145
|
-
|
146
143
|
end
|
@@ -1,10 +1,10 @@
|
|
1
|
-
require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'helper'))
|
2
2
|
|
3
3
|
class TestHelpers < Test::Unit::TestCase
|
4
4
|
|
5
5
|
HTML_STRING = "<div>omgwtfbbq</div>"
|
6
6
|
|
7
|
-
context "
|
7
|
+
context "#strip_tags" do
|
8
8
|
should "invoke Loofah.fragment.text" do
|
9
9
|
mock_doc = mock
|
10
10
|
Loofah.expects(:fragment).with(HTML_STRING).returns(mock_doc)
|
@@ -14,8 +14,8 @@ class TestHelpers < Test::Unit::TestCase
|
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
|
-
context "
|
18
|
-
should "invoke Loofah.scrub_fragment(:
|
17
|
+
context "#sanitize" do
|
18
|
+
should "invoke Loofah.scrub_fragment(:strip).to_s" do
|
19
19
|
mock_doc = mock
|
20
20
|
Loofah.expects(:fragment).with(HTML_STRING).returns(mock_doc)
|
21
21
|
mock_doc.expects(:scrub!).with(:strip).returns(mock_doc)
|
@@ -24,5 +24,4 @@ class TestHelpers < Test::Unit::TestCase
|
|
24
24
|
Loofah::Helpers.sanitize HTML_STRING
|
25
25
|
end
|
26
26
|
end
|
27
|
-
|
28
27
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'helper'))
|
2
2
|
|
3
3
|
class TestScrubber < Test::Unit::TestCase
|
4
4
|
|
@@ -147,10 +147,12 @@ class TestScrubber < Test::Unit::TestCase
|
|
147
147
|
setup do
|
148
148
|
@klass = Class.new(Loofah::Scrubber) do
|
149
149
|
attr_accessor :count
|
150
|
+
|
150
151
|
def initialize(direction=nil)
|
151
152
|
@direction = direction
|
152
153
|
@count = 0
|
153
154
|
end
|
155
|
+
|
154
156
|
def scrub(node)
|
155
157
|
@count += 1
|
156
158
|
Loofah::Scrubber::STOP
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'helper'))
|
2
|
+
|
3
|
+
class TestScrubbers < Test::Unit::TestCase
|
4
|
+
[ Loofah::HTML::Document, Loofah::HTML::DocumentFragment ].each do |klass|
|
5
|
+
context klass do
|
6
|
+
context "bad scrub method" do
|
7
|
+
should "raise a ScrubberNotFound exception" do
|
8
|
+
doc = klass.parse "<p>foo</p>"
|
9
|
+
assert_raises(Loofah::ScrubberNotFound) { doc.scrub! :frippery }
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'helper'))
|
2
2
|
|
3
3
|
class TestXssFoliate < Test::Unit::TestCase
|
4
4
|
|
@@ -59,8 +59,8 @@ class TestXssFoliate < Test::Unit::TestCase
|
|
59
59
|
should "calls the right scrubber" do
|
60
60
|
assert_nothing_raised(ArgumentError) { Post.xss_foliate :prune => :plain_text }
|
61
61
|
Loofah.expects(:scrub_fragment).with(HTML_STRING, :strip).once
|
62
|
-
Loofah.expects(:scrub_fragment).with(PLAIN_TEXT,
|
63
|
-
|
62
|
+
Loofah.expects(:scrub_fragment).with(PLAIN_TEXT, :prune).once
|
63
|
+
new_post.valid?
|
64
64
|
end
|
65
65
|
end
|
66
66
|
|
@@ -70,8 +70,8 @@ class TestXssFoliate < Test::Unit::TestCase
|
|
70
70
|
Post.xss_foliate :prune => [:plain_text, :html_string]
|
71
71
|
}
|
72
72
|
Loofah.expects(:scrub_fragment).with(HTML_STRING, :prune).once
|
73
|
-
Loofah.expects(:scrub_fragment).with(PLAIN_TEXT,
|
74
|
-
|
73
|
+
Loofah.expects(:scrub_fragment).with(PLAIN_TEXT, :prune).once
|
74
|
+
new_post.valid?
|
75
75
|
end
|
76
76
|
end
|
77
77
|
|
@@ -79,8 +79,8 @@ class TestXssFoliate < Test::Unit::TestCase
|
|
79
79
|
should "calls the right scrubber" do
|
80
80
|
assert_nothing_raised(ArgumentError) { Post.xss_foliate :prune => 'plain_text' }
|
81
81
|
Loofah.expects(:scrub_fragment).with(HTML_STRING, :strip).once
|
82
|
-
Loofah.expects(:scrub_fragment).with(PLAIN_TEXT,
|
83
|
-
|
82
|
+
Loofah.expects(:scrub_fragment).with(PLAIN_TEXT, :prune).once
|
83
|
+
new_post.valid?
|
84
84
|
end
|
85
85
|
end
|
86
86
|
|
@@ -90,8 +90,8 @@ class TestXssFoliate < Test::Unit::TestCase
|
|
90
90
|
Post.xss_foliate :prune => ['plain_text', 'html_string']
|
91
91
|
}
|
92
92
|
Loofah.expects(:scrub_fragment).with(HTML_STRING, :prune).once
|
93
|
-
Loofah.expects(:scrub_fragment).with(PLAIN_TEXT,
|
94
|
-
|
93
|
+
Loofah.expects(:scrub_fragment).with(PLAIN_TEXT, :prune).once
|
94
|
+
new_post.valid?
|
95
95
|
end
|
96
96
|
end
|
97
97
|
end
|
@@ -104,8 +104,8 @@ class TestXssFoliate < Test::Unit::TestCase
|
|
104
104
|
|
105
105
|
should "scrub all fields" do
|
106
106
|
mock_doc = mock
|
107
|
-
Loofah.expects(:scrub_fragment).with(HTML_STRING,
|
108
|
-
Loofah.expects(:scrub_fragment).with(PLAIN_TEXT,
|
107
|
+
Loofah.expects(:scrub_fragment).with(HTML_STRING, :strip).once.returns(mock_doc)
|
108
|
+
Loofah.expects(:scrub_fragment).with(PLAIN_TEXT, :strip).once.returns(mock_doc)
|
109
109
|
Loofah.expects(:scrub_fragment).with(INTEGER_VALUE, :strip).never
|
110
110
|
mock_doc.expects(:to_s).twice
|
111
111
|
assert new_post.valid?
|
@@ -119,11 +119,11 @@ class TestXssFoliate < Test::Unit::TestCase
|
|
119
119
|
|
120
120
|
should "not scrub omitted field" do
|
121
121
|
mock_doc = mock
|
122
|
-
Loofah.expects(:scrub_fragment).with(HTML_STRING,
|
123
|
-
Loofah.expects(:scrub_fragment).with(PLAIN_TEXT,
|
122
|
+
Loofah.expects(:scrub_fragment).with(HTML_STRING, :strip).once.returns(mock_doc)
|
123
|
+
Loofah.expects(:scrub_fragment).with(PLAIN_TEXT, :strip).never
|
124
124
|
Loofah.expects(:scrub_fragment).with(INTEGER_VALUE, :strip).never
|
125
125
|
mock_doc.expects(:to_s).once
|
126
|
-
|
126
|
+
new_post.valid?
|
127
127
|
end
|
128
128
|
end
|
129
129
|
|
@@ -135,11 +135,11 @@ class TestXssFoliate < Test::Unit::TestCase
|
|
135
135
|
|
136
136
|
should "not that field appropriately" do
|
137
137
|
mock_doc = mock
|
138
|
-
Loofah.expects(:scrub_fragment).with(HTML_STRING,
|
139
|
-
Loofah.expects(:scrub_fragment).with(PLAIN_TEXT,
|
138
|
+
Loofah.expects(:scrub_fragment).with(HTML_STRING, :strip).once.returns(mock_doc)
|
139
|
+
Loofah.expects(:scrub_fragment).with(PLAIN_TEXT, method).once.returns(mock_doc)
|
140
140
|
Loofah.expects(:scrub_fragment).with(INTEGER_VALUE, :strip).never
|
141
141
|
mock_doc.expects(:to_s).twice
|
142
|
-
|
142
|
+
new_post.valid?
|
143
143
|
end
|
144
144
|
end
|
145
145
|
end
|
@@ -150,10 +150,10 @@ class TestXssFoliate < Test::Unit::TestCase
|
|
150
150
|
end
|
151
151
|
|
152
152
|
should "not that field appropriately" do
|
153
|
-
Loofah.expects(:scrub_fragment).with(HTML_STRING,
|
154
|
-
Loofah.expects(:scrub_fragment).with(PLAIN_TEXT,
|
155
|
-
Loofah.expects(:scrub_fragment).with(INTEGER_VALUE, :strip).never
|
156
|
-
|
153
|
+
Loofah.expects(:scrub_fragment).with(HTML_STRING, :strip) .once
|
154
|
+
Loofah.expects(:scrub_fragment).with(PLAIN_TEXT, :escape).once
|
155
|
+
Loofah.expects(:scrub_fragment).with(INTEGER_VALUE, :strip) .never
|
156
|
+
new_post.valid?
|
157
157
|
end
|
158
158
|
end
|
159
159
|
end
|
@@ -166,7 +166,7 @@ class TestXssFoliate < Test::Unit::TestCase
|
|
166
166
|
|
167
167
|
should "not be valid after sanitizing" do
|
168
168
|
Loofah.expects(:scrub_fragment).with(WHITESPACEY, :strip).once
|
169
|
-
Loofah.expects(:scrub_fragment).with(PLAIN_TEXT,
|
169
|
+
Loofah.expects(:scrub_fragment).with(PLAIN_TEXT, :strip).once
|
170
170
|
assert ! new_post(:html_string => WHITESPACEY).valid?
|
171
171
|
end
|
172
172
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: loofah
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mike Dalessio
|
@@ -31,7 +31,7 @@ cert_chain:
|
|
31
31
|
FlqnTjy13J3nD30uxy9a1g==
|
32
32
|
-----END CERTIFICATE-----
|
33
33
|
|
34
|
-
date: 2010-02-
|
34
|
+
date: 2010-02-02 00:00:00 -05:00
|
35
35
|
default_executable:
|
36
36
|
dependencies:
|
37
37
|
- !ruby/object:Gem::Dependency
|
@@ -135,13 +135,15 @@ files:
|
|
135
135
|
- lib/loofah/xss_foliate.rb
|
136
136
|
- test/helper.rb
|
137
137
|
- test/html5/test_sanitizer.rb
|
138
|
-
- test/
|
139
|
-
- test/
|
140
|
-
- test/
|
141
|
-
- test/
|
142
|
-
- test/
|
143
|
-
- test/
|
144
|
-
- test/
|
138
|
+
- test/integration/test_ad_hoc.rb
|
139
|
+
- test/integration/test_helpers.rb
|
140
|
+
- test/integration/test_scrubbers.rb
|
141
|
+
- test/unit/test_active_record.rb
|
142
|
+
- test/unit/test_api.rb
|
143
|
+
- test/unit/test_helpers.rb
|
144
|
+
- test/unit/test_scrubber.rb
|
145
|
+
- test/unit/test_scrubbers.rb
|
146
|
+
- test/unit/test_xss_foliate.rb
|
145
147
|
has_rdoc: true
|
146
148
|
homepage: http://github.com/flavorjones/loofah
|
147
149
|
licenses: []
|
@@ -172,11 +174,13 @@ signing_key:
|
|
172
174
|
specification_version: 3
|
173
175
|
summary: Loofah is a general library for manipulating HTML/XML documents and fragments
|
174
176
|
test_files:
|
175
|
-
- test/
|
176
|
-
- test/
|
177
|
-
- test/
|
178
|
-
- test/
|
179
|
-
- test/
|
180
|
-
- test/
|
177
|
+
- test/integration/test_helpers.rb
|
178
|
+
- test/integration/test_scrubbers.rb
|
179
|
+
- test/integration/test_ad_hoc.rb
|
180
|
+
- test/unit/test_xss_foliate.rb
|
181
|
+
- test/unit/test_helpers.rb
|
182
|
+
- test/unit/test_scrubber.rb
|
183
|
+
- test/unit/test_scrubbers.rb
|
184
|
+
- test/unit/test_api.rb
|
185
|
+
- test/unit/test_active_record.rb
|
181
186
|
- test/html5/test_sanitizer.rb
|
182
|
-
- test/test_active_record.rb
|
metadata.gz.sig
CHANGED
Binary file
|
data/test/test_scrubbers.rb
DELETED
@@ -1,144 +0,0 @@
|
|
1
|
-
require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
|
2
|
-
|
3
|
-
class TestScrubber < Test::Unit::TestCase
|
4
|
-
|
5
|
-
[ Loofah::HTML::Document, Loofah::HTML::DocumentFragment ].each do |klass|
|
6
|
-
define_method "test_#{klass}_bad_sanitize_method" do
|
7
|
-
doc = klass.parse "<p>foo</p>"
|
8
|
-
assert_raises(Loofah::ScrubberNotFound) { doc.scrub! :frippery }
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
INVALID_FRAGMENT = "<invalid>foo<p>bar</p>bazz</invalid><div>quux</div>"
|
13
|
-
INVALID_ESCAPED = "<invalid>foo<p>bar</p>bazz</invalid><div>quux</div>"
|
14
|
-
INVALID_PRUNED = "<div>quux</div>"
|
15
|
-
INVALID_STRIPPED = "foo<p>bar</p>bazz<div>quux</div>"
|
16
|
-
|
17
|
-
WHITEWASH_FRAGMENT = "<o:div>no</o:div><div id='no'>foo</div><invalid>bar</invalid>"
|
18
|
-
WHITEWASH_RESULT = "<div>foo</div>"
|
19
|
-
|
20
|
-
NOFOLLOW_FRAGMENT = '<a href="http://www.example.com/">Click here</a>'
|
21
|
-
NOFOLLOW_RESULT = '<a href="http://www.example.com/" rel="nofollow">Click here</a>'
|
22
|
-
|
23
|
-
def test_document_escape_bad_tags
|
24
|
-
doc = Loofah::HTML::Document.parse "<html><body>#{INVALID_FRAGMENT}</body></html>"
|
25
|
-
result = doc.scrub! :escape
|
26
|
-
|
27
|
-
assert_equal INVALID_ESCAPED, doc.xpath('/html/body').inner_html
|
28
|
-
assert_equal doc, result
|
29
|
-
end
|
30
|
-
|
31
|
-
def test_fragment_escape_bad_tags
|
32
|
-
doc = Loofah::HTML::DocumentFragment.parse "<div>#{INVALID_FRAGMENT}</div>"
|
33
|
-
result = doc.scrub! :escape
|
34
|
-
|
35
|
-
assert_equal INVALID_ESCAPED, doc.xpath("./div").inner_html
|
36
|
-
assert_equal doc, result
|
37
|
-
end
|
38
|
-
|
39
|
-
def test_document_prune_bad_tags
|
40
|
-
doc = Loofah::HTML::Document.parse "<html><body>#{INVALID_FRAGMENT}</body></html>"
|
41
|
-
result = doc.scrub! :prune
|
42
|
-
|
43
|
-
assert_equal INVALID_PRUNED, doc.xpath('/html/body').inner_html
|
44
|
-
assert_equal doc, result
|
45
|
-
end
|
46
|
-
|
47
|
-
def test_fragment_prune_bad_tags
|
48
|
-
doc = Loofah::HTML::DocumentFragment.parse "<div>#{INVALID_FRAGMENT}</div>"
|
49
|
-
result = doc.scrub! :prune
|
50
|
-
|
51
|
-
assert_equal INVALID_PRUNED, doc.xpath("./div").inner_html
|
52
|
-
assert_equal doc, result
|
53
|
-
end
|
54
|
-
|
55
|
-
def test_document_strip_bad_tags
|
56
|
-
doc = Loofah::HTML::Document.parse "<html><body>#{INVALID_FRAGMENT}</body></html>"
|
57
|
-
result = doc.scrub! :strip
|
58
|
-
|
59
|
-
assert_equal INVALID_STRIPPED, doc.xpath('/html/body').inner_html
|
60
|
-
assert_equal doc, result
|
61
|
-
end
|
62
|
-
|
63
|
-
def test_fragment_strip_bad_tags
|
64
|
-
doc = Loofah::HTML::DocumentFragment.parse "<div>#{INVALID_FRAGMENT}</div>"
|
65
|
-
result = doc.scrub! :strip
|
66
|
-
|
67
|
-
assert_equal INVALID_STRIPPED, doc.xpath("./div").inner_html
|
68
|
-
assert_equal doc, result
|
69
|
-
end
|
70
|
-
|
71
|
-
def test_document_whitewash
|
72
|
-
doc = Loofah::HTML::Document.parse "<html><body>#{WHITEWASH_FRAGMENT}</body></html>"
|
73
|
-
result = doc.scrub! :whitewash
|
74
|
-
|
75
|
-
assert_equal WHITEWASH_RESULT, doc.xpath('/html/body').inner_html
|
76
|
-
assert_equal doc, result
|
77
|
-
end
|
78
|
-
|
79
|
-
def test_fragment_whitewash
|
80
|
-
doc = Loofah::HTML::DocumentFragment.parse "<div>#{WHITEWASH_FRAGMENT}</div>"
|
81
|
-
result = doc.scrub! :whitewash
|
82
|
-
|
83
|
-
assert_equal WHITEWASH_RESULT, doc.xpath("./div").inner_html
|
84
|
-
assert_equal doc, result
|
85
|
-
end
|
86
|
-
|
87
|
-
def test_document_nofollow
|
88
|
-
doc = Loofah::HTML::Document.parse "<html><body>#{NOFOLLOW_FRAGMENT}</body></html>"
|
89
|
-
result = doc.scrub! :nofollow
|
90
|
-
|
91
|
-
assert_equal NOFOLLOW_RESULT, doc.xpath('/html/body').inner_html
|
92
|
-
assert_equal doc, result
|
93
|
-
end
|
94
|
-
|
95
|
-
def test_fragment_nofollow
|
96
|
-
doc = Loofah::HTML::DocumentFragment.parse "<div>#{NOFOLLOW_FRAGMENT}</div>"
|
97
|
-
result = doc.scrub! :nofollow
|
98
|
-
|
99
|
-
assert_equal NOFOLLOW_RESULT, doc.xpath("./div").inner_html
|
100
|
-
assert_equal doc, result
|
101
|
-
end
|
102
|
-
|
103
|
-
def test_fragment_shortcut
|
104
|
-
mock_doc = mock
|
105
|
-
Loofah.expects(:fragment).with(:string_or_io).returns(mock_doc)
|
106
|
-
mock_doc.expects(:scrub!).with(:method)
|
107
|
-
|
108
|
-
Loofah.scrub_fragment(:string_or_io, :method)
|
109
|
-
end
|
110
|
-
|
111
|
-
def test_document_shortcut
|
112
|
-
mock_doc = mock
|
113
|
-
Loofah.expects(:document).with(:string_or_io).returns(mock_doc)
|
114
|
-
mock_doc.expects(:scrub!).with(:method)
|
115
|
-
|
116
|
-
Loofah.scrub_document(:string_or_io, :method)
|
117
|
-
end
|
118
|
-
|
119
|
-
def test_document_to_s
|
120
|
-
doc = Loofah.scrub_document "<html><head><title>quux</title></head><body><div>foo</div></body></html>", :prune
|
121
|
-
assert_not_nil doc.xpath("/html").first
|
122
|
-
assert_not_nil doc.xpath("/html/head").first
|
123
|
-
assert_not_nil doc.xpath("/html/body").first
|
124
|
-
|
125
|
-
assert_contains doc.to_s, /<!DOCTYPE/
|
126
|
-
assert_contains doc.to_s, /<html>/
|
127
|
-
assert_contains doc.to_s, /<head>/
|
128
|
-
assert_contains doc.to_s, /<body>/
|
129
|
-
end
|
130
|
-
|
131
|
-
def test_document_serialize
|
132
|
-
doc = Loofah.scrub_document "<html><head><title>quux</title></head><body><div>foo</div></body></html>", :prune
|
133
|
-
|
134
|
-
assert_not_nil doc.xpath("/html").first
|
135
|
-
assert_not_nil doc.xpath("/html/head").first
|
136
|
-
assert_not_nil doc.xpath("/html/body").first
|
137
|
-
|
138
|
-
assert_contains doc.serialize, /<!DOCTYPE/
|
139
|
-
assert_contains doc.serialize, /<html>/
|
140
|
-
assert_contains doc.serialize, /<head>/
|
141
|
-
assert_contains doc.serialize, /<body>/
|
142
|
-
end
|
143
|
-
|
144
|
-
end
|