loofah 2.1.0.rc2 → 2.1.0
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.
- checksums.yaml +4 -4
- data/{CHANGELOG.rdoc → CHANGELOG.md} +31 -25
- data/Gemfile +5 -5
- data/Manifest.txt +1 -1
- data/README.rdoc +1 -1
- data/Rakefile +6 -2
- data/lib/loofah.rb +1 -1
- data/lib/loofah/html5/scrub.rb +8 -0
- data/lib/loofah/html5/whitelist.rb +5 -1
- data/lib/loofah/scrubber.rb +11 -0
- data/lib/loofah/scrubbers.rb +33 -2
- data/test/html5/test_sanitizer.rb +38 -1
- data/test/integration/test_helpers.rb +1 -1
- data/test/integration/test_scrubbers.rb +53 -7
- metadata +39 -25
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 13e19d4b2c9e5b356dbb76d7948604f0d8dbcce3
|
4
|
+
data.tar.gz: 6a74873ffe59ebca17b477993527d0766eb234ac
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ccdaffd6dd04b57d35941082b95f0605ff8778d167b4d37fca6fa9654b7734c1eb820507e604c395d97a0bfa6dd8196db32200fa6e0ac8779a969252424ca9fe
|
7
|
+
data.tar.gz: 43650a3a8b6c437f3bf323b1aa288ed1b0aa3e51cc0710ff508e2443a066c82c50fdccbaadd9e30910176f8fc1488c8613b5d75c591534aab2fc4b6e2cfca8a3
|
@@ -1,26 +1,32 @@
|
|
1
|
-
|
1
|
+
# Changelog
|
2
2
|
|
3
|
-
|
3
|
+
## 2.1.0 / 2017-09-24
|
4
4
|
|
5
5
|
Notes:
|
6
6
|
|
7
7
|
* Re-implemented CSS parsing and sanitization using the {crass}[https://github.com/rgrove/crass] library. #91
|
8
|
-
* Updated tests to ensure support for libxml 2.9.3.
|
9
8
|
|
10
9
|
|
11
|
-
|
10
|
+
Features:
|
11
|
+
|
12
|
+
* Added :noopener HTML scrubber (Thanks, @tastycode!)
|
13
|
+
* Support `data` URIs with the following media types: text/plain, text/css, image/png, image/gif, image/jpeg, image/svg+xml. #101, #120. (Thanks, @mrpasquini!)
|
14
|
+
|
15
|
+
|
16
|
+
Bugfixes:
|
12
17
|
|
18
|
+
* The :unprintable scrubber now scrubs unprintable characters in CDATA nodes (like `<script>`). #124
|
13
19
|
* Allow negative values in CSS properties. Restores functionality that was reverted in v2.0.3. #91
|
14
20
|
|
15
21
|
|
16
|
-
|
22
|
+
## 2.0.3 / 2015-08-17
|
17
23
|
|
18
24
|
Bug fixes:
|
19
25
|
|
20
26
|
* Revert support for negative values in CSS properties due to slow performance. #90 (Related to #85.)
|
21
27
|
|
22
28
|
|
23
|
-
|
29
|
+
## 2.0.2 / 2015-05-05
|
24
30
|
|
25
31
|
Bug fixes:
|
26
32
|
|
@@ -29,7 +35,7 @@ Bug fixes:
|
|
29
35
|
* Allow negative values in CSS properties. #85 (Thanks, @siddhartham!)
|
30
36
|
|
31
37
|
|
32
|
-
|
38
|
+
## 2.0.1 / 2014-08-21
|
33
39
|
|
34
40
|
Bug fixes:
|
35
41
|
|
@@ -41,7 +47,7 @@ Notes:
|
|
41
47
|
* Extracted HTML5::Scrub#scrub_css_attribute to accommodate the Rails integration work. (Thanks, @kaspth!)
|
42
48
|
|
43
49
|
|
44
|
-
|
50
|
+
## 2.0.0 / 2014-05-09
|
45
51
|
|
46
52
|
Compatibility notes:
|
47
53
|
|
@@ -64,12 +70,12 @@ Bug fixes:
|
|
64
70
|
* HTML5 sanitizers now allow negative arguments to CSS. #64 (Thanks, Jon Calhoun!)
|
65
71
|
|
66
72
|
|
67
|
-
|
73
|
+
## 1.2.1 (2012-04-14)
|
68
74
|
|
69
75
|
* Declaring encoding in html5/scrub.rb. Without this, use of the ruby -KU option would cause havoc. (#32)
|
70
76
|
|
71
77
|
|
72
|
-
|
78
|
+
## 1.2.0 (2011-08-08)
|
73
79
|
|
74
80
|
Enhancements:
|
75
81
|
|
@@ -77,7 +83,7 @@ Enhancements:
|
|
77
83
|
* Improving ActionView integration.
|
78
84
|
|
79
85
|
|
80
|
-
|
86
|
+
## 1.1.0 (2011-08-08)
|
81
87
|
|
82
88
|
Enhancements:
|
83
89
|
|
@@ -87,7 +93,7 @@ Enhancements:
|
|
87
93
|
* Don't explode when encountering UTF-8 URIs. (#25, #29)
|
88
94
|
|
89
95
|
|
90
|
-
|
96
|
+
## 1.0.0 (2010-10-26)
|
91
97
|
|
92
98
|
Notes:
|
93
99
|
|
@@ -95,7 +101,7 @@ Notes:
|
|
95
101
|
* Removed DEPRECATIONS.rdoc documenting 0.3.0 API changes.
|
96
102
|
|
97
103
|
|
98
|
-
|
104
|
+
## 0.4.7 (2010-03-09)
|
99
105
|
|
100
106
|
Enhancements:
|
101
107
|
|
@@ -108,7 +114,7 @@ Enhancements:
|
|
108
114
|
will return unescaped HTML entities by passing :encode_special_chars => false.
|
109
115
|
|
110
116
|
|
111
|
-
|
117
|
+
## 0.4.4, 0.4.5, 0.4.6 (2010-02-01)
|
112
118
|
|
113
119
|
Enhancements:
|
114
120
|
|
@@ -119,7 +125,7 @@ Bug fixes:
|
|
119
125
|
* Loofah::XssFoliate was not properly escaping HTML entities when implicitly scrubbing a string attribute. GH #17
|
120
126
|
|
121
127
|
|
122
|
-
|
128
|
+
## 0.4.3 (2010-01-29)
|
123
129
|
|
124
130
|
Enhancements:
|
125
131
|
|
@@ -133,7 +139,7 @@ Miscellaneous:
|
|
133
139
|
be safe, always use an initializer file.
|
134
140
|
|
135
141
|
|
136
|
-
|
142
|
+
## 0.4.2 (2010-01-22)
|
137
143
|
|
138
144
|
Enhancements:
|
139
145
|
|
@@ -152,14 +158,14 @@ Miscellaneous:
|
|
152
158
|
* IRC channel is now \#loofah on freenode.
|
153
159
|
|
154
160
|
|
155
|
-
|
161
|
+
## 0.4.1 (2009-11-23)
|
156
162
|
|
157
163
|
Bugfix:
|
158
164
|
|
159
165
|
* Manifest fixed. Whoops.
|
160
166
|
|
161
167
|
|
162
|
-
|
168
|
+
## 0.4.0 (2009-11-21)
|
163
169
|
|
164
170
|
Enhancements:
|
165
171
|
|
@@ -170,14 +176,14 @@ Enhancements:
|
|
170
176
|
|
171
177
|
|
172
178
|
|
173
|
-
|
179
|
+
## 0.3.1 (2009-10-12)
|
174
180
|
|
175
181
|
Bug fixes:
|
176
182
|
|
177
183
|
* Scrubbed Documents properly render html, head and body tags when serialized.
|
178
184
|
|
179
185
|
|
180
|
-
|
186
|
+
## 0.3.0 (2009-10-06)
|
181
187
|
|
182
188
|
Enhancements:
|
183
189
|
|
@@ -192,7 +198,7 @@ Deprecations:
|
|
192
198
|
details on the equivalent calls with the post-0.2 API.
|
193
199
|
|
194
200
|
|
195
|
-
|
201
|
+
## 0.2.2 (2009-09-30)
|
196
202
|
|
197
203
|
Enhancements:
|
198
204
|
|
@@ -200,7 +206,7 @@ Enhancements:
|
|
200
206
|
(was previously in a before_save)
|
201
207
|
|
202
208
|
|
203
|
-
|
209
|
+
## 0.2.1 (2009-09-19)
|
204
210
|
|
205
211
|
Enhancements:
|
206
212
|
|
@@ -215,7 +221,7 @@ Bugfixes:
|
|
215
221
|
(Thanks Josh Nichols!)
|
216
222
|
|
217
223
|
|
218
|
-
|
224
|
+
## 0.2.0 (2009-09-11)
|
219
225
|
|
220
226
|
* Swank new API.
|
221
227
|
* ActiveRecord extension.
|
@@ -225,11 +231,11 @@ Bugfixes:
|
|
225
231
|
* Documentation! Hey!
|
226
232
|
|
227
233
|
|
228
|
-
|
234
|
+
## 0.1.2 (2009-04-30)
|
229
235
|
|
230
236
|
* Added whitewashing -- removal of all attributes and namespaced nodes. You know, for microsofty HTML.
|
231
237
|
|
232
238
|
|
233
|
-
|
239
|
+
## 0.1.0 (2009-02-10)
|
234
240
|
|
235
241
|
* Birthday!
|
data/Gemfile
CHANGED
@@ -4,19 +4,19 @@
|
|
4
4
|
|
5
5
|
source "https://rubygems.org/"
|
6
6
|
|
7
|
-
|
8
|
-
gem "nokogiri", :path => "../nokogiri"
|
7
|
+
gem "nokogiri", ">=1.5.9"
|
9
8
|
gem "crass", "~>1.0.2"
|
10
9
|
|
11
|
-
gem "rdoc", "~>4.0", :group => [:development, :test]
|
12
10
|
gem "rake", ">=0.8", :group => [:development, :test]
|
13
11
|
gem "minitest", "~>2.2", :group => [:development, :test]
|
14
|
-
gem "rr", "~>1.
|
12
|
+
gem "rr", "~>1.2.0", :group => [:development, :test]
|
15
13
|
gem "json", ">=0", :group => [:development, :test]
|
16
14
|
gem "hoe-gemspec", ">=0", :group => [:development, :test]
|
17
15
|
gem "hoe-debugging", ">=0", :group => [:development, :test]
|
18
16
|
gem "hoe-bundler", ">=0", :group => [:development, :test]
|
19
17
|
gem "hoe-git", ">=0", :group => [:development, :test]
|
20
|
-
gem "
|
18
|
+
gem "concourse", ">=0.14.0", :group => [:development, :test]
|
19
|
+
gem "rdoc", "~>4.0", :group => [:development, :test]
|
20
|
+
gem "hoe", "~>3.16", :group => [:development, :test]
|
21
21
|
|
22
22
|
# vim: syntax=ruby
|
data/Manifest.txt
CHANGED
data/README.rdoc
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
= Loofah {<img src="https://travis-ci.org/flavorjones/loofah.
|
1
|
+
= Loofah {<img src="https://travis-ci.org/flavorjones/loofah.svg?branch=master" alt="Build Status" />}[https://travis-ci.org/flavorjones/loofah]
|
2
2
|
|
3
3
|
* https://github.com/flavorjones/loofah
|
4
4
|
* http://rubydoc.info/github/flavorjones/loofah/master/frames
|
data/Rakefile
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
gem 'hoe', '>= 2.3.0'
|
3
3
|
require 'hoe'
|
4
|
+
require 'concourse'
|
4
5
|
|
5
6
|
Hoe.plugin :git
|
6
7
|
Hoe.plugin :gemspec
|
@@ -12,7 +13,7 @@ Hoe.spec "loofah" do
|
|
12
13
|
developer "Bryan Helmkamp", "bryan@brynary.com"
|
13
14
|
|
14
15
|
self.extra_rdoc_files = FileList["*.rdoc"]
|
15
|
-
self.history_file = "CHANGELOG.
|
16
|
+
self.history_file = "CHANGELOG.md"
|
16
17
|
self.readme_file = "README.rdoc"
|
17
18
|
self.license "MIT"
|
18
19
|
|
@@ -21,12 +22,13 @@ Hoe.spec "loofah" do
|
|
21
22
|
|
22
23
|
extra_dev_deps << ["rake", ">=0.8"]
|
23
24
|
extra_dev_deps << ["minitest", "~>2.2"]
|
24
|
-
extra_dev_deps << ["rr", "~>1.
|
25
|
+
extra_dev_deps << ["rr", "~>1.2.0"]
|
25
26
|
extra_dev_deps << ["json", ">=0"]
|
26
27
|
extra_dev_deps << ["hoe-gemspec", ">=0"]
|
27
28
|
extra_dev_deps << ["hoe-debugging", ">=0"]
|
28
29
|
extra_dev_deps << ["hoe-bundler", ">=0"]
|
29
30
|
extra_dev_deps << ["hoe-git", ">=0"]
|
31
|
+
extra_dev_deps << ["concourse", ">=0.14.0"]
|
30
32
|
end
|
31
33
|
|
32
34
|
task :gemspec do
|
@@ -73,3 +75,5 @@ desc "generate whitelists from W3C specifications"
|
|
73
75
|
task :generate_whitelists do
|
74
76
|
load "tasks/generate-whitelists"
|
75
77
|
end
|
78
|
+
|
79
|
+
Concourse.new("loofah").create_tasks!
|
data/lib/loofah.rb
CHANGED
data/lib/loofah/html5/scrub.rb
CHANGED
@@ -41,6 +41,14 @@ module Loofah
|
|
41
41
|
if val_unescaped =~ /^[a-z0-9][-+.a-z0-9]*:/ && ! WhiteList::ALLOWED_PROTOCOLS.include?(val_unescaped.split(WhiteList::PROTOCOL_SEPARATOR)[0])
|
42
42
|
attr_node.remove
|
43
43
|
next
|
44
|
+
elsif val_unescaped.split(WhiteList::PROTOCOL_SEPARATOR)[0] == 'data'
|
45
|
+
# permit only allowed data mediatypes
|
46
|
+
mediatype = val_unescaped.split(WhiteList::PROTOCOL_SEPARATOR)[1]
|
47
|
+
mediatype, base64 = mediatype.split(';')[0..1] if mediatype
|
48
|
+
if mediatype && !WhiteList::ALLOWED_URI_DATA_MEDIATYPES.include?(mediatype)
|
49
|
+
attr_node.remove
|
50
|
+
next
|
51
|
+
end
|
44
52
|
end
|
45
53
|
end
|
46
54
|
if WhiteList::SVG_ATTR_VAL_ALLOWS_REF.include?(attr_name)
|
@@ -145,7 +145,10 @@ module Loofah
|
|
145
145
|
PROTOCOL_SEPARATOR = /:|(�*58)|(p)|(�*3a)|(%|%)3A/i
|
146
146
|
|
147
147
|
ACCEPTABLE_PROTOCOLS = Set.new %w[ed2k ftp http https irc mailto news gopher nntp
|
148
|
-
telnet webcal xmpp callto feed urn aim rsync tag ssh sftp rtsp afs]
|
148
|
+
telnet webcal xmpp callto feed urn aim rsync tag ssh sftp rtsp afs data]
|
149
|
+
|
150
|
+
ACCEPTABLE_URI_DATA_MEDIATYPES = Set.new %w[text/plain text/css image/png image/gif
|
151
|
+
image/jpeg image/svg+xml]
|
149
152
|
|
150
153
|
# subclasses may define their own versions of these constants
|
151
154
|
ALLOWED_ELEMENTS = ACCEPTABLE_ELEMENTS + MATHML_ELEMENTS + SVG_ELEMENTS
|
@@ -154,6 +157,7 @@ module Loofah
|
|
154
157
|
ALLOWED_CSS_KEYWORDS = ACCEPTABLE_CSS_KEYWORDS
|
155
158
|
ALLOWED_SVG_PROPERTIES = ACCEPTABLE_SVG_PROPERTIES
|
156
159
|
ALLOWED_PROTOCOLS = ACCEPTABLE_PROTOCOLS
|
160
|
+
ALLOWED_URI_DATA_MEDIATYPES = ACCEPTABLE_URI_DATA_MEDIATYPES
|
157
161
|
|
158
162
|
VOID_ELEMENTS = Set.new %w[
|
159
163
|
base
|
data/lib/loofah/scrubber.rb
CHANGED
@@ -86,6 +86,17 @@ module Loofah
|
|
86
86
|
raise ScrubberNotFound, "No scrub method has been defined on #{self.class.to_s}"
|
87
87
|
end
|
88
88
|
|
89
|
+
#
|
90
|
+
# If the attribute is not set, add it
|
91
|
+
# If the attribute is set, don't overwrite the existing value
|
92
|
+
#
|
93
|
+
def append_attribute(node, attribute, value)
|
94
|
+
current_value = node.get_attribute(attribute) || ''
|
95
|
+
current_values = current_value.split(/\s+/)
|
96
|
+
updated_value = current_values | [value]
|
97
|
+
node.set_attribute(attribute, updated_value.join(' '))
|
98
|
+
end
|
99
|
+
|
89
100
|
private
|
90
101
|
|
91
102
|
def html5lib_sanitize(node)
|
data/lib/loofah/scrubbers.rb
CHANGED
@@ -59,6 +59,15 @@ module Loofah
|
|
59
59
|
# => "ohai! <a href='http://www.myswarmysite.com/' rel="nofollow">I like your blog post</a>"
|
60
60
|
#
|
61
61
|
#
|
62
|
+
# === Loofah::Scrubbers::NoOpener / scrub!(:noopener)
|
63
|
+
#
|
64
|
+
# +:noopener+ adds a rel="noopener" attribute to all links
|
65
|
+
#
|
66
|
+
# link_farmers_markup = "ohai! <a href='http://www.myswarmysite.com/'>I like your blog post</a>"
|
67
|
+
# Loofah.fragment(link_farmers_markup).scrub!(:noopener)
|
68
|
+
# => "ohai! <a href='http://www.myswarmysite.com/' rel="noopener">I like your blog post</a>"
|
69
|
+
#
|
70
|
+
#
|
62
71
|
# === Loofah::Scrubbers::Unprintable / scrub!(:unprintable)
|
63
72
|
#
|
64
73
|
# +:unprintable+ removes unprintable Unicode characters.
|
@@ -192,7 +201,28 @@ module Loofah
|
|
192
201
|
|
193
202
|
def scrub(node)
|
194
203
|
return CONTINUE unless (node.type == Nokogiri::XML::Node::ELEMENT_NODE) && (node.name == 'a')
|
195
|
-
node
|
204
|
+
append_attribute(node, 'rel', 'nofollow')
|
205
|
+
return STOP
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
#
|
210
|
+
# === scrub!(:noopener)
|
211
|
+
#
|
212
|
+
# +:noopener+ adds a rel="noopener" attribute to all links
|
213
|
+
#
|
214
|
+
# link_farmers_markup = "ohai! <a href='http://www.myswarmysite.com/'>I like your blog post</a>"
|
215
|
+
# Loofah.fragment(link_farmers_markup).scrub!(:noopener)
|
216
|
+
# => "ohai! <a href='http://www.myswarmysite.com/' rel="noopener">I like your blog post</a>"
|
217
|
+
#
|
218
|
+
class NoOpener < Scrubber
|
219
|
+
def initialize
|
220
|
+
@direction = :top_down
|
221
|
+
end
|
222
|
+
|
223
|
+
def scrub(node)
|
224
|
+
return CONTINUE unless (node.type == Nokogiri::XML::Node::ELEMENT_NODE) && (node.name == 'a')
|
225
|
+
append_attribute(node, 'rel', 'noopener')
|
196
226
|
return STOP
|
197
227
|
end
|
198
228
|
end
|
@@ -231,7 +261,7 @@ module Loofah
|
|
231
261
|
end
|
232
262
|
|
233
263
|
def scrub(node)
|
234
|
-
if node.type == Nokogiri::XML::Node::TEXT_NODE
|
264
|
+
if node.type == Nokogiri::XML::Node::TEXT_NODE || node.type == Nokogiri::XML::Node::CDATA_SECTION_NODE
|
235
265
|
node.content = node.content.gsub(/\u2028|\u2029/, '')
|
236
266
|
end
|
237
267
|
CONTINUE
|
@@ -247,6 +277,7 @@ module Loofah
|
|
247
277
|
:whitewash => Whitewash,
|
248
278
|
:strip => Strip,
|
249
279
|
:nofollow => NoFollow,
|
280
|
+
:noopener => NoOpener,
|
250
281
|
:newline_block_elements => NewlineBlockElements,
|
251
282
|
:unprintable => Unprintable
|
252
283
|
}
|
@@ -34,7 +34,7 @@ class Html5TestSanitizer < Loofah::TestCase
|
|
34
34
|
def assert_completes_in_reasonable_time &block
|
35
35
|
t0 = Time.now
|
36
36
|
block.call
|
37
|
-
assert_in_delta t0, Time.now, 0.
|
37
|
+
assert_in_delta t0, Time.now, 0.1 # arbitrary seconds
|
38
38
|
end
|
39
39
|
|
40
40
|
(HTML5::WhiteList::ALLOWED_ELEMENTS).each do |tag_name|
|
@@ -136,6 +136,41 @@ class Html5TestSanitizer < Loofah::TestCase
|
|
136
136
|
check_sanitization(input, output, output, output)
|
137
137
|
end
|
138
138
|
end
|
139
|
+
|
140
|
+
HTML5::WhiteList::ALLOWED_URI_DATA_MEDIATYPES.each do |data_uri_type|
|
141
|
+
define_method "test_should_allow_data_#{data_uri_type}_uris" do
|
142
|
+
input = %(<a href="data:#{data_uri_type}">foo</a>)
|
143
|
+
output = "<a href='data:#{data_uri_type}'>foo</a>"
|
144
|
+
check_sanitization(input, output, output, output)
|
145
|
+
|
146
|
+
input = %(<a href="data:#{data_uri_type};base64,R0lGODlhAQABA">foo</a>)
|
147
|
+
output = "<a href='data:#{data_uri_type};base64,R0lGODlhAQABA'>foo</a>"
|
148
|
+
check_sanitization(input, output, output, output)
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
HTML5::WhiteList::ALLOWED_URI_DATA_MEDIATYPES.each do |data_uri_type|
|
153
|
+
define_method "test_should_allow_uppercase_data_#{data_uri_type}_uris" do
|
154
|
+
input = %(<a href="DATA:#{data_uri_type.upcase}">foo</a>)
|
155
|
+
output = "<a href='DATA:#{data_uri_type.upcase}'>foo</a>"
|
156
|
+
check_sanitization(input, output, output, output)
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
def test_should_disallow_other_uri_mediatypes
|
161
|
+
input = %(<a href="data:foo">foo</a>)
|
162
|
+
output = "<a>foo</a>"
|
163
|
+
check_sanitization(input, output, output, output)
|
164
|
+
|
165
|
+
input = %(<a href="data:image/xxx">foo</a>)
|
166
|
+
output = "<a>foo</a>"
|
167
|
+
check_sanitization(input, output, output, output)
|
168
|
+
|
169
|
+
input = %(<a href="data:image/xxx;base64,R0lGODlhAQABA">foo</a>)
|
170
|
+
output = "<a>foo</a>"
|
171
|
+
check_sanitization(input, output, output, output)
|
172
|
+
end
|
173
|
+
|
139
174
|
|
140
175
|
HTML5::WhiteList::SVG_ALLOW_LOCAL_HREF.each do |tag_name|
|
141
176
|
next unless HTML5::WhiteList::ALLOWED_ELEMENTS.include?(tag_name)
|
@@ -241,6 +276,8 @@ class Html5TestSanitizer < Loofah::TestCase
|
|
241
276
|
end
|
242
277
|
|
243
278
|
def test_issue_90_slow_regex
|
279
|
+
skip("timing tests are hard to make pass and have little regression-testing value")
|
280
|
+
|
244
281
|
html = %q{<span style="background: url('data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2232%22%20height%3D%2232%22%20viewBox%3D%220%200%2032%2032%22%3E%3Cpath%20fill%3D%22%23D4C8AE%22%20d%3D%22M0%200h32v32h-32z%22%2F%3E%3Cpath%20fill%3D%22%2383604B%22%20d%3D%22M0%200h31.99v11.75h-31.99z%22%2F%3E%3Cpath%20fill%3D%22%233D2319%22%20d%3D%22M0%2011.5h32v.5h-32z%22%2F%3E%3Cpath%20fill%3D%22%23F83651%22%20d%3D%22M5%200h1v10.5h-1z%22%2F%3E%3Cpath%20fill%3D%22%23FCD050%22%20d%3D%22M6%200h1v10.5h-1z%22%2F%3E%3Cpath%20fill%3D%22%2371C797%22%20d%3D%22M7%200h1v10.5h-1z%22%2F%3E%3Cpath%20fill%3D%22%23509CF9%22%20d%3D%22M8%200h1v10.5h-1z%22%2F%3E%3ClinearGradient%20id%3D%22a%22%20gradientUnits%3D%22userSpaceOnUse%22%20x1%3D%2224.996%22%20y1%3D%2210.5%22%20x2%3D%2224.996%22%20y2%3D%224.5%22%3E%3Cstop%20offset%3D%220%22%20stop-color%3D%22%23796055%22%2F%3E%3Cstop%20offset%3D%22.434%22%20stop-color%3D%22%23614C43%22%2F%3E%3Cstop%20offset%3D%221%22%20stop-color%3D%22%233D2D28%22%2F%3E%3C%2FlinearGradient%3E%3Cpath%20fill%3D%22url(%23a)%22%20d%3D%22M28%208.5c0%201.1-.9%202-2%202h-2c-1.1%200-2-.9-2-2v-2c0-1.1.9-2%202-2h2c1.1%200%202%20.9%202%202v2z%22%2F%3E%3Cpath%20fill%3D%22%235F402E%22%20d%3D%22M28%208c0%201.1-.9%202-2%202h-2c-1.1%200-2-.9-2-2v-2c0-1.1.9-2%202-2h2c1.1%200%202%20.9%202%202v2z%22%2F%3E%3C');"></span>}
|
245
282
|
|
246
283
|
assert_completes_in_reasonable_time {
|
@@ -37,7 +37,7 @@ class IntegrationTestHelpers < Loofah::TestCase
|
|
37
37
|
|
38
38
|
context ".sanitize_css" do
|
39
39
|
it "removes unsafe css properties" do
|
40
|
-
assert_match
|
40
|
+
assert_match(/display:\s*block;\s*background-color:\s*blue;/, Loofah::Helpers.sanitize_css("display:block;background-image:url(http://www.ragingplatypus.com/i/cam-full.jpg);background-color:blue"))
|
41
41
|
end
|
42
42
|
end
|
43
43
|
end
|
@@ -13,8 +13,17 @@ class IntegrationTestScrubbers < Loofah::TestCase
|
|
13
13
|
NOFOLLOW_FRAGMENT = '<a href="http://www.example.com/">Click here</a>'
|
14
14
|
NOFOLLOW_RESULT = '<a href="http://www.example.com/" rel="nofollow">Click here</a>'
|
15
15
|
|
16
|
-
|
17
|
-
|
16
|
+
NOFOLLOW_WITH_REL_FRAGMENT = '<a href="http://www.example.com/" rel="noopener">Click here</a>'
|
17
|
+
NOFOLLOW_WITH_REL_RESULT = '<a href="http://www.example.com/" rel="noopener nofollow">Click here</a>'
|
18
|
+
|
19
|
+
NOOPENER_FRAGMENT = '<a href="http://www.example.com/">Click here</a>'
|
20
|
+
NOOPENER_RESULT = '<a href="http://www.example.com/" rel="noopener">Click here</a>'
|
21
|
+
|
22
|
+
NOOPENER_WITH_REL_FRAGMENT = '<a href="http://www.example.com/" rel="nofollow">Click here</a>'
|
23
|
+
NOOPENER_WITH_REL_RESULT = '<a href="http://www.example.com/" rel="nofollow noopener">Click here</a>'
|
24
|
+
|
25
|
+
UNPRINTABLE_FRAGMENT = "<b>Lo\u2029ofah ro\u2028cks!</b><script>x\u2028y</script>"
|
26
|
+
UNPRINTABLE_RESULT = "<b>Loofah rocks!</b><script>xy</script>"
|
18
27
|
|
19
28
|
ENTITY_FRAGMENT = "<p>this is < that "&" the other > boo'ya</p><div>w00t</div>"
|
20
29
|
ENTITY_TEXT = %Q(this is < that "&" the other > boo\'yaw00t)
|
@@ -244,12 +253,49 @@ class IntegrationTestScrubbers < Loofah::TestCase
|
|
244
253
|
end
|
245
254
|
|
246
255
|
context ":nofollow" do
|
247
|
-
it "add a 'nofollow' attribute to hyperlinks" do
|
248
|
-
doc = Loofah::HTML::DocumentFragment.parse "<div>#{NOFOLLOW_FRAGMENT}</div>"
|
249
|
-
result = doc.scrub! :nofollow
|
250
256
|
|
251
|
-
|
252
|
-
|
257
|
+
context "for a hyperlink that does not have a rel attribute" do
|
258
|
+
it "add a 'nofollow' attribute to hyperlinks" do
|
259
|
+
doc = Loofah::HTML::DocumentFragment.parse "<div>#{NOFOLLOW_FRAGMENT}</div>"
|
260
|
+
result = doc.scrub! :nofollow
|
261
|
+
|
262
|
+
assert_equal NOFOLLOW_RESULT, doc.xpath("./div").inner_html
|
263
|
+
assert_equal doc, result
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
context "for a hyperlink that does have a rel attribute" do
|
268
|
+
it "appends nofollow to rel attribute" do
|
269
|
+
doc = Loofah::HTML::DocumentFragment.parse "<div>#{NOFOLLOW_WITH_REL_FRAGMENT}</div>"
|
270
|
+
result = doc.scrub! :nofollow
|
271
|
+
|
272
|
+
assert_equal NOFOLLOW_WITH_REL_RESULT, doc.xpath("./div").inner_html
|
273
|
+
assert_equal doc, result
|
274
|
+
end
|
275
|
+
end
|
276
|
+
|
277
|
+
|
278
|
+
end
|
279
|
+
|
280
|
+
context ":noopener" do
|
281
|
+
context "for a hyperlink without a 'rel' attribute" do
|
282
|
+
it "add a 'noopener' attribute to hyperlinks" do
|
283
|
+
doc = Loofah::HTML::DocumentFragment.parse "<div>#{NOOPENER_FRAGMENT}</div>"
|
284
|
+
result = doc.scrub! :noopener
|
285
|
+
|
286
|
+
assert_equal NOOPENER_RESULT, doc.xpath("./div").inner_html
|
287
|
+
assert_equal doc, result
|
288
|
+
end
|
289
|
+
end
|
290
|
+
|
291
|
+
context "for a hyperlink that does have a rel attribute" do
|
292
|
+
it "appends 'noopener' to 'rel' attribute" do
|
293
|
+
doc = Loofah::HTML::DocumentFragment.parse "<div>#{NOOPENER_WITH_REL_FRAGMENT}</div>"
|
294
|
+
result = doc.scrub! :noopener
|
295
|
+
|
296
|
+
assert_equal NOOPENER_WITH_REL_RESULT, doc.xpath("./div").inner_html
|
297
|
+
assert_equal doc, result
|
298
|
+
end
|
253
299
|
end
|
254
300
|
end
|
255
301
|
|
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: 2.1.0
|
4
|
+
version: 2.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mike Dalessio
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2017-09-24 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: nokogiri
|
@@ -39,20 +39,6 @@ dependencies:
|
|
39
39
|
- - "~>"
|
40
40
|
- !ruby/object:Gem::Version
|
41
41
|
version: 1.0.2
|
42
|
-
- !ruby/object:Gem::Dependency
|
43
|
-
name: rdoc
|
44
|
-
requirement: !ruby/object:Gem::Requirement
|
45
|
-
requirements:
|
46
|
-
- - "~>"
|
47
|
-
- !ruby/object:Gem::Version
|
48
|
-
version: '4.0'
|
49
|
-
type: :development
|
50
|
-
prerelease: false
|
51
|
-
version_requirements: !ruby/object:Gem::Requirement
|
52
|
-
requirements:
|
53
|
-
- - "~>"
|
54
|
-
- !ruby/object:Gem::Version
|
55
|
-
version: '4.0'
|
56
42
|
- !ruby/object:Gem::Dependency
|
57
43
|
name: rake
|
58
44
|
requirement: !ruby/object:Gem::Requirement
|
@@ -87,14 +73,14 @@ dependencies:
|
|
87
73
|
requirements:
|
88
74
|
- - "~>"
|
89
75
|
- !ruby/object:Gem::Version
|
90
|
-
version: 1.
|
76
|
+
version: 1.2.0
|
91
77
|
type: :development
|
92
78
|
prerelease: false
|
93
79
|
version_requirements: !ruby/object:Gem::Requirement
|
94
80
|
requirements:
|
95
81
|
- - "~>"
|
96
82
|
- !ruby/object:Gem::Version
|
97
|
-
version: 1.
|
83
|
+
version: 1.2.0
|
98
84
|
- !ruby/object:Gem::Dependency
|
99
85
|
name: json
|
100
86
|
requirement: !ruby/object:Gem::Requirement
|
@@ -165,20 +151,48 @@ dependencies:
|
|
165
151
|
- - ">="
|
166
152
|
- !ruby/object:Gem::Version
|
167
153
|
version: '0'
|
154
|
+
- !ruby/object:Gem::Dependency
|
155
|
+
name: concourse
|
156
|
+
requirement: !ruby/object:Gem::Requirement
|
157
|
+
requirements:
|
158
|
+
- - ">="
|
159
|
+
- !ruby/object:Gem::Version
|
160
|
+
version: 0.14.0
|
161
|
+
type: :development
|
162
|
+
prerelease: false
|
163
|
+
version_requirements: !ruby/object:Gem::Requirement
|
164
|
+
requirements:
|
165
|
+
- - ">="
|
166
|
+
- !ruby/object:Gem::Version
|
167
|
+
version: 0.14.0
|
168
|
+
- !ruby/object:Gem::Dependency
|
169
|
+
name: rdoc
|
170
|
+
requirement: !ruby/object:Gem::Requirement
|
171
|
+
requirements:
|
172
|
+
- - "~>"
|
173
|
+
- !ruby/object:Gem::Version
|
174
|
+
version: '4.0'
|
175
|
+
type: :development
|
176
|
+
prerelease: false
|
177
|
+
version_requirements: !ruby/object:Gem::Requirement
|
178
|
+
requirements:
|
179
|
+
- - "~>"
|
180
|
+
- !ruby/object:Gem::Version
|
181
|
+
version: '4.0'
|
168
182
|
- !ruby/object:Gem::Dependency
|
169
183
|
name: hoe
|
170
184
|
requirement: !ruby/object:Gem::Requirement
|
171
185
|
requirements:
|
172
186
|
- - "~>"
|
173
187
|
- !ruby/object:Gem::Version
|
174
|
-
version: '3.
|
188
|
+
version: '3.16'
|
175
189
|
type: :development
|
176
190
|
prerelease: false
|
177
191
|
version_requirements: !ruby/object:Gem::Requirement
|
178
192
|
requirements:
|
179
193
|
- - "~>"
|
180
194
|
- !ruby/object:Gem::Version
|
181
|
-
version: '3.
|
195
|
+
version: '3.16'
|
182
196
|
description: |-
|
183
197
|
Loofah is a general library for manipulating and transforming HTML/XML
|
184
198
|
documents and fragments. It's built on top of Nokogiri and libxml2, so
|
@@ -198,13 +212,13 @@ email:
|
|
198
212
|
executables: []
|
199
213
|
extensions: []
|
200
214
|
extra_rdoc_files:
|
201
|
-
- CHANGELOG.
|
215
|
+
- CHANGELOG.md
|
202
216
|
- MIT-LICENSE.txt
|
203
217
|
- Manifest.txt
|
204
218
|
- README.rdoc
|
205
219
|
files:
|
206
220
|
- ".gemtest"
|
207
|
-
- CHANGELOG.
|
221
|
+
- CHANGELOG.md
|
208
222
|
- Gemfile
|
209
223
|
- MIT-LICENSE.txt
|
210
224
|
- Manifest.txt
|
@@ -257,12 +271,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
257
271
|
version: '0'
|
258
272
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
259
273
|
requirements:
|
260
|
-
- - "
|
274
|
+
- - ">="
|
261
275
|
- !ruby/object:Gem::Version
|
262
|
-
version:
|
276
|
+
version: '0'
|
263
277
|
requirements: []
|
264
278
|
rubyforge_project:
|
265
|
-
rubygems_version: 2.
|
279
|
+
rubygems_version: 2.6.12
|
266
280
|
signing_key:
|
267
281
|
specification_version: 4
|
268
282
|
summary: Loofah is a general library for manipulating and transforming HTML/XML documents
|