loofah 0.4.2 → 2.25.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.md +604 -0
- data/MIT-LICENSE.txt +3 -1
- data/README.md +410 -0
- data/SECURITY.md +18 -0
- data/lib/loofah/concerns.rb +207 -0
- data/lib/loofah/elements.rb +98 -0
- data/lib/loofah/helpers.rb +91 -4
- data/lib/loofah/html4/document.rb +17 -0
- data/lib/loofah/html4/document_fragment.rb +15 -0
- data/lib/loofah/html5/document.rb +17 -0
- data/lib/loofah/html5/document_fragment.rb +15 -0
- data/lib/loofah/html5/libxml2_workarounds.rb +28 -0
- data/lib/loofah/html5/safelist.rb +1058 -0
- data/lib/loofah/html5/scrub.rb +211 -40
- data/lib/loofah/metahelpers.rb +18 -0
- data/lib/loofah/scrubber.rb +31 -13
- data/lib/loofah/scrubbers.rb +262 -31
- data/lib/loofah/version.rb +6 -0
- data/lib/loofah/xml/document.rb +2 -0
- data/lib/loofah/xml/document_fragment.rb +6 -9
- data/lib/loofah.rb +131 -52
- metadata +79 -158
- data/CHANGELOG.rdoc +0 -92
- data/DEPRECATED.rdoc +0 -12
- data/Manifest.txt +0 -34
- data/README.rdoc +0 -330
- data/Rakefile +0 -61
- data/TODO.rdoc +0 -4
- data/benchmark/benchmark.rb +0 -149
- data/benchmark/fragment.html +0 -96
- data/benchmark/helper.rb +0 -73
- data/benchmark/www.slashdot.com.html +0 -2560
- data/init.rb +0 -1
- data/lib/loofah/active_record.rb +0 -62
- data/lib/loofah/html/document.rb +0 -22
- data/lib/loofah/html/document_fragment.rb +0 -46
- data/lib/loofah/html5/whitelist.rb +0 -174
- data/lib/loofah/instance_methods.rb +0 -77
- data/lib/loofah/xss_foliate.rb +0 -212
- data/test/helper.rb +0 -8
- data/test/html5/test_sanitizer.rb +0 -248
- data/test/test_active_record.rb +0 -146
- data/test/test_ad_hoc.rb +0 -272
- data/test/test_api.rb +0 -128
- data/test/test_helpers.rb +0 -28
- data/test/test_scrubber.rb +0 -227
- data/test/test_scrubbers.rb +0 -144
- data/test/test_xss_foliate.rb +0 -171
- data.tar.gz.sig +0 -0
- metadata.gz.sig +0 -2
data/test/test_api.rb
DELETED
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
|
|
2
|
-
|
|
3
|
-
class TestApi < Test::Unit::TestCase
|
|
4
|
-
|
|
5
|
-
HTML = "<div>a</div>\n<div>b</div>"
|
|
6
|
-
XML_FRAGMENT = "<div>a</div>\n<div>b</div>"
|
|
7
|
-
XML = "<root>#{XML_FRAGMENT}</root>"
|
|
8
|
-
|
|
9
|
-
def test_loofah_document
|
|
10
|
-
doc = Loofah.document(HTML)
|
|
11
|
-
assert_html_documentish doc
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
def test_loofah_fragment
|
|
15
|
-
doc = Loofah.fragment(HTML)
|
|
16
|
-
assert_html_fragmentish doc
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
def test_loofah_xml_document
|
|
20
|
-
doc = Loofah.xml_document(XML)
|
|
21
|
-
assert_xml_documentish doc
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def test_loofah_xml_fragment
|
|
25
|
-
doc = Loofah.xml_fragment(XML_FRAGMENT)
|
|
26
|
-
assert_xml_fragmentish doc
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
def test_loofah_html_document_parse_method
|
|
30
|
-
doc = Loofah::HTML::Document.parse(HTML)
|
|
31
|
-
assert_html_documentish doc
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
def test_loofah_xml_document_parse_method
|
|
35
|
-
doc = Loofah::XML::Document.parse(XML)
|
|
36
|
-
assert_xml_documentish doc
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
def test_loofah_html_document_fragment_parse_method
|
|
40
|
-
doc = Loofah::HTML::DocumentFragment.parse(HTML)
|
|
41
|
-
assert_html_fragmentish doc
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
def test_loofah_xml_document_fragment_parse_method
|
|
45
|
-
doc = Loofah::XML::DocumentFragment.parse(XML_FRAGMENT)
|
|
46
|
-
assert_xml_fragmentish doc
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
def test_loofah_document_scrub!
|
|
50
|
-
doc = Loofah.document(HTML).scrub!(:strip)
|
|
51
|
-
assert_html_documentish doc
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
def test_loofah_fragment_scrub!
|
|
55
|
-
doc = Loofah.fragment(HTML).scrub!(:strip)
|
|
56
|
-
assert_html_fragmentish doc
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
def test_loofah_xml_document_scrub!
|
|
60
|
-
scrubber = Loofah::Scrubber.new { |node| }
|
|
61
|
-
doc = Loofah.xml_document(XML).scrub!(scrubber)
|
|
62
|
-
assert_xml_documentish doc
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
def test_loofah_xml_fragment_scrub!
|
|
66
|
-
scrubber = Loofah::Scrubber.new { |node| }
|
|
67
|
-
doc = Loofah.xml_fragment(XML_FRAGMENT).scrub!(scrubber)
|
|
68
|
-
assert_xml_fragmentish doc
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
def test_loofah_html_document_node_scrub!
|
|
72
|
-
doc = Loofah.document(HTML)
|
|
73
|
-
assert(node = doc.at_css("div"))
|
|
74
|
-
node.scrub!(:strip)
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
def test_loofah_html_fragment_node_scrub!
|
|
78
|
-
doc = Loofah.fragment(HTML)
|
|
79
|
-
assert(node = doc.at_css("div"))
|
|
80
|
-
node.scrub!(:strip)
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
def test_loofah_xml_document_node_scrub!
|
|
84
|
-
doc = Loofah.document(XML)
|
|
85
|
-
assert(node = doc.at_css("div"))
|
|
86
|
-
node.scrub!(:strip)
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
def test_loofah_xml_fragment_node_scrub!
|
|
90
|
-
doc = Loofah.fragment(XML)
|
|
91
|
-
assert(node = doc.at_css("div"))
|
|
92
|
-
node.scrub!(:strip)
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
def test_loofah_nodeset_scrub!
|
|
96
|
-
doc = Loofah.document(HTML)
|
|
97
|
-
assert(node_set = doc.css("div"))
|
|
98
|
-
assert_instance_of Nokogiri::XML::NodeSet, node_set
|
|
99
|
-
node_set.scrub!(:strip)
|
|
100
|
-
end
|
|
101
|
-
|
|
102
|
-
private
|
|
103
|
-
|
|
104
|
-
def assert_html_documentish(doc)
|
|
105
|
-
assert_kind_of Nokogiri::HTML::Document, doc
|
|
106
|
-
assert_kind_of Loofah::HTML::Document, doc
|
|
107
|
-
assert_equal HTML, doc.xpath("/html/body").inner_html
|
|
108
|
-
end
|
|
109
|
-
|
|
110
|
-
def assert_html_fragmentish(doc)
|
|
111
|
-
assert_kind_of Nokogiri::HTML::DocumentFragment, doc
|
|
112
|
-
assert_kind_of Loofah::HTML::DocumentFragment, doc
|
|
113
|
-
assert_equal HTML, doc.inner_html
|
|
114
|
-
end
|
|
115
|
-
|
|
116
|
-
def assert_xml_documentish(doc)
|
|
117
|
-
assert_kind_of Nokogiri::XML::Document, doc
|
|
118
|
-
assert_kind_of Loofah::XML::Document, doc
|
|
119
|
-
assert_equal XML, doc.root.to_xml
|
|
120
|
-
end
|
|
121
|
-
|
|
122
|
-
def assert_xml_fragmentish(doc)
|
|
123
|
-
assert_kind_of Nokogiri::XML::DocumentFragment, doc
|
|
124
|
-
assert_kind_of Loofah::XML::DocumentFragment, doc
|
|
125
|
-
assert_equal XML_FRAGMENT, doc.children.to_xml
|
|
126
|
-
end
|
|
127
|
-
|
|
128
|
-
end
|
data/test/test_helpers.rb
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
|
|
2
|
-
|
|
3
|
-
class TestHelpers < Test::Unit::TestCase
|
|
4
|
-
|
|
5
|
-
HTML_STRING = "<div>omgwtfbbq</div>"
|
|
6
|
-
|
|
7
|
-
context "when calling strip_tags" do
|
|
8
|
-
should "invoke Loofah.fragment.text" do
|
|
9
|
-
mock_doc = mock
|
|
10
|
-
Loofah.expects(:fragment).with(HTML_STRING).returns(mock_doc)
|
|
11
|
-
mock_doc.expects(:text)
|
|
12
|
-
|
|
13
|
-
Loofah::Helpers.strip_tags HTML_STRING
|
|
14
|
-
end
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
context "when calling sanitize" do
|
|
18
|
-
should "invoke Loofah.scrub_fragment(:escape).to_s" do
|
|
19
|
-
mock_doc = mock
|
|
20
|
-
Loofah.expects(:fragment).with(HTML_STRING).returns(mock_doc)
|
|
21
|
-
mock_doc.expects(:scrub!).with(:strip).returns(mock_doc)
|
|
22
|
-
mock_doc.expects(:to_s)
|
|
23
|
-
|
|
24
|
-
Loofah::Helpers.sanitize HTML_STRING
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
end
|
data/test/test_scrubber.rb
DELETED
|
@@ -1,227 +0,0 @@
|
|
|
1
|
-
require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
|
|
2
|
-
|
|
3
|
-
class TestScrubber < Test::Unit::TestCase
|
|
4
|
-
|
|
5
|
-
FRAGMENT = "<span>hello</span><span>goodbye</span>"
|
|
6
|
-
FRAGMENT_NODE_COUNT = 4 # span, text, span, text
|
|
7
|
-
FRAGMENT_NODE_STOP_TOP_DOWN = 2 # span, span
|
|
8
|
-
DOCUMENT = "<html><head><link></link></head><body><span>hello</span><span>goodbye</span></body></html>"
|
|
9
|
-
DOCUMENT_NODE_COUNT = 8 # html, head, link, body, span, text, span, text
|
|
10
|
-
DOCUMENT_NODE_STOP_TOP_DOWN = 1 # html
|
|
11
|
-
|
|
12
|
-
context "receiving a block" do
|
|
13
|
-
setup do
|
|
14
|
-
@count = 0
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
context "returning CONTINUE" do
|
|
18
|
-
setup do
|
|
19
|
-
@scrubber = Loofah::Scrubber.new do |node|
|
|
20
|
-
@count += 1
|
|
21
|
-
Loofah::Scrubber::CONTINUE
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
should "operate properly on a fragment" do
|
|
26
|
-
Loofah.scrub_fragment(FRAGMENT, @scrubber)
|
|
27
|
-
assert_equal FRAGMENT_NODE_COUNT, @count
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
should "operate properly on a document" do
|
|
31
|
-
Loofah.scrub_document(DOCUMENT, @scrubber)
|
|
32
|
-
assert_equal DOCUMENT_NODE_COUNT, @count
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
context "returning STOP" do
|
|
37
|
-
setup do
|
|
38
|
-
@scrubber = Loofah::Scrubber.new do |node|
|
|
39
|
-
@count += 1
|
|
40
|
-
Loofah::Scrubber::STOP
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
should "operate as top-down on a fragment" do
|
|
45
|
-
Loofah.scrub_fragment(FRAGMENT, @scrubber)
|
|
46
|
-
assert_equal FRAGMENT_NODE_STOP_TOP_DOWN, @count
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
should "operate as top-down on a document" do
|
|
50
|
-
Loofah.scrub_document(DOCUMENT, @scrubber)
|
|
51
|
-
assert_equal DOCUMENT_NODE_STOP_TOP_DOWN, @count
|
|
52
|
-
end
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
context "returning neither CONTINUE nor STOP" do
|
|
56
|
-
setup do
|
|
57
|
-
@scrubber = Loofah::Scrubber.new do |node|
|
|
58
|
-
@count += 1
|
|
59
|
-
end
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
should "act as if CONTINUE was returned" do
|
|
63
|
-
Loofah.scrub_fragment(FRAGMENT, @scrubber)
|
|
64
|
-
assert_equal FRAGMENT_NODE_COUNT, @count
|
|
65
|
-
end
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
context "not specifying direction" do
|
|
69
|
-
setup do
|
|
70
|
-
@scrubber = Loofah::Scrubber.new() do |node|
|
|
71
|
-
@count += 1
|
|
72
|
-
Loofah::Scrubber::STOP
|
|
73
|
-
end
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
should "operate as top-down on a fragment" do
|
|
77
|
-
Loofah.scrub_fragment(FRAGMENT, @scrubber)
|
|
78
|
-
assert_equal FRAGMENT_NODE_STOP_TOP_DOWN, @count
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
should "operate as top-down on a document" do
|
|
82
|
-
Loofah.scrub_document(DOCUMENT, @scrubber)
|
|
83
|
-
assert_equal DOCUMENT_NODE_STOP_TOP_DOWN, @count
|
|
84
|
-
end
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
context "specifying top-down direction" do
|
|
88
|
-
setup do
|
|
89
|
-
@scrubber = Loofah::Scrubber.new(:direction => :top_down) do |node|
|
|
90
|
-
@count += 1
|
|
91
|
-
Loofah::Scrubber::STOP
|
|
92
|
-
end
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
should "operate as top-down on a fragment" do
|
|
96
|
-
Loofah.scrub_fragment(FRAGMENT, @scrubber)
|
|
97
|
-
assert_equal FRAGMENT_NODE_STOP_TOP_DOWN, @count
|
|
98
|
-
end
|
|
99
|
-
|
|
100
|
-
should "operate as top-down on a document" do
|
|
101
|
-
Loofah.scrub_document(DOCUMENT, @scrubber)
|
|
102
|
-
assert_equal DOCUMENT_NODE_STOP_TOP_DOWN, @count
|
|
103
|
-
end
|
|
104
|
-
end
|
|
105
|
-
|
|
106
|
-
context "specifying bottom-up direction" do
|
|
107
|
-
setup do
|
|
108
|
-
@scrubber = Loofah::Scrubber.new(:direction => :bottom_up) do |node|
|
|
109
|
-
@count += 1
|
|
110
|
-
end
|
|
111
|
-
end
|
|
112
|
-
|
|
113
|
-
should "operate as bottom-up on a fragment" do
|
|
114
|
-
Loofah.scrub_fragment(FRAGMENT, @scrubber)
|
|
115
|
-
assert_equal FRAGMENT_NODE_COUNT, @count
|
|
116
|
-
end
|
|
117
|
-
|
|
118
|
-
should "operate as bottom-up on a document" do
|
|
119
|
-
Loofah.scrub_document(DOCUMENT, @scrubber)
|
|
120
|
-
assert_equal DOCUMENT_NODE_COUNT, @count
|
|
121
|
-
end
|
|
122
|
-
end
|
|
123
|
-
|
|
124
|
-
context "invalid direction" do
|
|
125
|
-
should "raise an exception" do
|
|
126
|
-
assert_raises(ArgumentError) {
|
|
127
|
-
Loofah::Scrubber.new(:direction => :quux) { }
|
|
128
|
-
}
|
|
129
|
-
end
|
|
130
|
-
end
|
|
131
|
-
|
|
132
|
-
context "given a block taking zero arguments" do
|
|
133
|
-
setup do
|
|
134
|
-
@scrubber = Loofah::Scrubber.new do
|
|
135
|
-
@count += 1
|
|
136
|
-
end
|
|
137
|
-
end
|
|
138
|
-
|
|
139
|
-
should "work anyway, shrug" do
|
|
140
|
-
Loofah.scrub_fragment(FRAGMENT, @scrubber)
|
|
141
|
-
assert_equal FRAGMENT_NODE_COUNT, @count
|
|
142
|
-
end
|
|
143
|
-
end
|
|
144
|
-
end
|
|
145
|
-
|
|
146
|
-
context "defining a new Scrubber class" do
|
|
147
|
-
setup do
|
|
148
|
-
@klass = Class.new(Loofah::Scrubber) do
|
|
149
|
-
attr_accessor :count
|
|
150
|
-
def initialize(direction=nil)
|
|
151
|
-
@direction = direction
|
|
152
|
-
@count = 0
|
|
153
|
-
end
|
|
154
|
-
def scrub(node)
|
|
155
|
-
@count += 1
|
|
156
|
-
Loofah::Scrubber::STOP
|
|
157
|
-
end
|
|
158
|
-
end
|
|
159
|
-
end
|
|
160
|
-
|
|
161
|
-
context "when not specifying direction" do
|
|
162
|
-
setup do
|
|
163
|
-
@scrubber = @klass.new
|
|
164
|
-
assert_nil @scrubber.direction
|
|
165
|
-
end
|
|
166
|
-
|
|
167
|
-
should "operate as top-down on a fragment" do
|
|
168
|
-
Loofah.scrub_fragment(FRAGMENT, @scrubber)
|
|
169
|
-
assert_equal FRAGMENT_NODE_STOP_TOP_DOWN, @scrubber.count
|
|
170
|
-
end
|
|
171
|
-
|
|
172
|
-
should "operate as top-down on a document" do
|
|
173
|
-
Loofah.scrub_document(DOCUMENT, @scrubber)
|
|
174
|
-
assert_equal DOCUMENT_NODE_STOP_TOP_DOWN, @scrubber.count
|
|
175
|
-
end
|
|
176
|
-
end
|
|
177
|
-
|
|
178
|
-
context "when direction is specified as top_down" do
|
|
179
|
-
setup do
|
|
180
|
-
@scrubber = @klass.new(:top_down)
|
|
181
|
-
assert_equal :top_down, @scrubber.direction
|
|
182
|
-
end
|
|
183
|
-
|
|
184
|
-
should "operate as top-down on a fragment" do
|
|
185
|
-
Loofah.scrub_fragment(FRAGMENT, @scrubber)
|
|
186
|
-
assert_equal FRAGMENT_NODE_STOP_TOP_DOWN, @scrubber.count
|
|
187
|
-
end
|
|
188
|
-
|
|
189
|
-
should "operate as top-down on a document" do
|
|
190
|
-
Loofah.scrub_document(DOCUMENT, @scrubber)
|
|
191
|
-
assert_equal DOCUMENT_NODE_STOP_TOP_DOWN, @scrubber.count
|
|
192
|
-
end
|
|
193
|
-
end
|
|
194
|
-
|
|
195
|
-
context "when direction is specified as bottom_up" do
|
|
196
|
-
setup do
|
|
197
|
-
@scrubber = @klass.new(:bottom_up)
|
|
198
|
-
assert_equal :bottom_up, @scrubber.direction
|
|
199
|
-
end
|
|
200
|
-
|
|
201
|
-
should "operate as bottom-up on a fragment" do
|
|
202
|
-
Loofah.scrub_fragment(FRAGMENT, @scrubber)
|
|
203
|
-
assert_equal FRAGMENT_NODE_COUNT, @scrubber.count
|
|
204
|
-
end
|
|
205
|
-
|
|
206
|
-
should "operate as bottom-up on a document" do
|
|
207
|
-
Loofah.scrub_document(DOCUMENT, @scrubber)
|
|
208
|
-
assert_equal DOCUMENT_NODE_COUNT, @scrubber.count
|
|
209
|
-
end
|
|
210
|
-
end
|
|
211
|
-
end
|
|
212
|
-
|
|
213
|
-
context "creating a new Scrubber class with no scrub method" do
|
|
214
|
-
setup do
|
|
215
|
-
@klass = Class.new(Loofah::Scrubber) do
|
|
216
|
-
def initialize ; end
|
|
217
|
-
end
|
|
218
|
-
@scrubber = @klass.new
|
|
219
|
-
end
|
|
220
|
-
|
|
221
|
-
should "raise an exception" do
|
|
222
|
-
assert_raises(Loofah::ScrubberNotFound) {
|
|
223
|
-
Loofah.scrub_fragment(FRAGMENT, @scrubber)
|
|
224
|
-
}
|
|
225
|
-
end
|
|
226
|
-
end
|
|
227
|
-
end
|
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
|
data/test/test_xss_foliate.rb
DELETED
|
@@ -1,171 +0,0 @@
|
|
|
1
|
-
require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
|
|
2
|
-
|
|
3
|
-
class TestXssFoliate < Test::Unit::TestCase
|
|
4
|
-
|
|
5
|
-
HTML_STRING = "<div>omgwtfbbq</div>"
|
|
6
|
-
PLAIN_TEXT = "vanilla text"
|
|
7
|
-
INTEGER_VALUE = "1234"
|
|
8
|
-
WHITESPACEY = " <br> "
|
|
9
|
-
|
|
10
|
-
def new_post(overrides={})
|
|
11
|
-
Post.new({:html_string => HTML_STRING, :plain_text => PLAIN_TEXT, :not_a_string => INTEGER_VALUE}.merge(overrides))
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
context "with a Post model" do
|
|
15
|
-
setup do
|
|
16
|
-
ActsAsFu.build_model(:posts) do
|
|
17
|
-
string :plain_text
|
|
18
|
-
string :html_string
|
|
19
|
-
integer :not_a_string
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
context "#xss_foliated?" do
|
|
24
|
-
context "when xss_foliate has not been called" do
|
|
25
|
-
should "return false" do
|
|
26
|
-
assert ! Post.xss_foliated?
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
context "when xss_foliate has been called with no options" do
|
|
31
|
-
setup do
|
|
32
|
-
Post.xss_foliate
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
should "return true" do
|
|
36
|
-
assert Post.xss_foliated?
|
|
37
|
-
end
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
context "when xss_foliate has been called with options" do
|
|
41
|
-
setup do
|
|
42
|
-
Post.xss_foliate :prune => :plain_text
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
should "return true" do
|
|
46
|
-
assert Post.xss_foliated?
|
|
47
|
-
end
|
|
48
|
-
end
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
context "#xss_foliate" do
|
|
52
|
-
context "when passed invalid option" do
|
|
53
|
-
should "raise ArgumentError" do
|
|
54
|
-
assert_raise(ArgumentError) { Post.xss_foliate :quux => [:foo] }
|
|
55
|
-
end
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
context "when passed a symbol" do
|
|
59
|
-
should "do the right thing" do
|
|
60
|
-
assert_nothing_raised(ArgumentError) { Post.xss_foliate :prune => :plain_text }
|
|
61
|
-
Loofah.expects(:scrub_fragment).with(HTML_STRING, :strip).once
|
|
62
|
-
Loofah.expects(:scrub_fragment).with(PLAIN_TEXT, :prune).once
|
|
63
|
-
assert new_post.valid?
|
|
64
|
-
end
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
context "when passed an array of symbols" do
|
|
68
|
-
should "do the right thing" do
|
|
69
|
-
assert_nothing_raised(ArgumentError) {
|
|
70
|
-
Post.xss_foliate :prune => [:plain_text, :html_string]
|
|
71
|
-
}
|
|
72
|
-
Loofah.expects(:scrub_fragment).with(HTML_STRING, :prune).once
|
|
73
|
-
Loofah.expects(:scrub_fragment).with(PLAIN_TEXT, :prune).once
|
|
74
|
-
assert new_post.valid?
|
|
75
|
-
end
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
context "when passed a string" do
|
|
79
|
-
should "do the right thing" do
|
|
80
|
-
assert_nothing_raised(ArgumentError) { Post.xss_foliate :prune => 'plain_text' }
|
|
81
|
-
Loofah.expects(:scrub_fragment).with(HTML_STRING, :strip).once
|
|
82
|
-
Loofah.expects(:scrub_fragment).with(PLAIN_TEXT, :prune).once
|
|
83
|
-
assert new_post.valid?
|
|
84
|
-
end
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
context "when passed an array of strings" do
|
|
88
|
-
should "do the right thing" do
|
|
89
|
-
assert_nothing_raised(ArgumentError) {
|
|
90
|
-
Post.xss_foliate :prune => ['plain_text', 'html_string']
|
|
91
|
-
}
|
|
92
|
-
Loofah.expects(:scrub_fragment).with(HTML_STRING, :prune).once
|
|
93
|
-
Loofah.expects(:scrub_fragment).with(PLAIN_TEXT, :prune).once
|
|
94
|
-
assert new_post.valid?
|
|
95
|
-
end
|
|
96
|
-
end
|
|
97
|
-
end
|
|
98
|
-
|
|
99
|
-
context "declaring scrubbed fields" do
|
|
100
|
-
context "on all fields" do
|
|
101
|
-
setup do
|
|
102
|
-
Post.xss_foliate
|
|
103
|
-
end
|
|
104
|
-
|
|
105
|
-
should "scrub all fields" do
|
|
106
|
-
mock_doc = mock
|
|
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
|
-
Loofah.expects(:scrub_fragment).with(INTEGER_VALUE, :strip).never
|
|
110
|
-
mock_doc.expects(:text).twice
|
|
111
|
-
assert new_post.valid?
|
|
112
|
-
end
|
|
113
|
-
end
|
|
114
|
-
|
|
115
|
-
context "omitting one field" do
|
|
116
|
-
setup do
|
|
117
|
-
Post.xss_foliate :except => [:plain_text]
|
|
118
|
-
end
|
|
119
|
-
|
|
120
|
-
should "not scrub omitted field" do
|
|
121
|
-
Loofah.expects(:scrub_fragment).with(HTML_STRING, :strip).once
|
|
122
|
-
Loofah.expects(:scrub_fragment).with(PLAIN_TEXT, :strip).never
|
|
123
|
-
Loofah.expects(:scrub_fragment).with(INTEGER_VALUE, :strip).never
|
|
124
|
-
assert new_post.valid?
|
|
125
|
-
end
|
|
126
|
-
end
|
|
127
|
-
|
|
128
|
-
[:strip, :escape, :prune].each do |method|
|
|
129
|
-
context "declaring one field to be scrubbed with #{method}" do
|
|
130
|
-
setup do
|
|
131
|
-
Post.xss_foliate method => [:plain_text]
|
|
132
|
-
end
|
|
133
|
-
|
|
134
|
-
should "not that field appropriately" do
|
|
135
|
-
Loofah.expects(:scrub_fragment).with(HTML_STRING, :strip).once
|
|
136
|
-
Loofah.expects(:scrub_fragment).with(PLAIN_TEXT, method).once
|
|
137
|
-
Loofah.expects(:scrub_fragment).with(INTEGER_VALUE, :strip).never
|
|
138
|
-
assert new_post.valid?
|
|
139
|
-
end
|
|
140
|
-
end
|
|
141
|
-
end
|
|
142
|
-
|
|
143
|
-
context "declaring one field to be scrubbed with html5lib_sanitize" do
|
|
144
|
-
setup do
|
|
145
|
-
Post.xss_foliate :html5lib_sanitize => [:plain_text]
|
|
146
|
-
end
|
|
147
|
-
|
|
148
|
-
should "not that field appropriately" do
|
|
149
|
-
Loofah.expects(:scrub_fragment).with(HTML_STRING, :strip).once
|
|
150
|
-
Loofah.expects(:scrub_fragment).with(PLAIN_TEXT, :escape).once
|
|
151
|
-
Loofah.expects(:scrub_fragment).with(INTEGER_VALUE, :strip).never
|
|
152
|
-
assert new_post.valid?
|
|
153
|
-
end
|
|
154
|
-
end
|
|
155
|
-
end
|
|
156
|
-
|
|
157
|
-
context "invalid model data" do
|
|
158
|
-
setup do
|
|
159
|
-
Post.validates_presence_of :html_string
|
|
160
|
-
Post.xss_foliate
|
|
161
|
-
end
|
|
162
|
-
|
|
163
|
-
should "not be valid after sanitizing" do
|
|
164
|
-
Loofah.expects(:scrub_fragment).with(WHITESPACEY, :strip).once
|
|
165
|
-
Loofah.expects(:scrub_fragment).with(PLAIN_TEXT, :strip).once
|
|
166
|
-
assert ! new_post(:html_string => WHITESPACEY).valid?
|
|
167
|
-
end
|
|
168
|
-
end
|
|
169
|
-
|
|
170
|
-
end
|
|
171
|
-
end
|
data.tar.gz.sig
DELETED
|
Binary file
|
metadata.gz.sig
DELETED