loofah 2.2.1 → 2.4.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 +5 -5
- data/CHANGELOG.md +107 -32
- data/Gemfile +10 -9
- data/Manifest.txt +3 -1
- data/README.md +11 -17
- data/Rakefile +32 -20
- data/SECURITY.md +1 -1
- data/lib/loofah.rb +16 -15
- data/lib/loofah/elements.rb +1 -0
- data/lib/loofah/helpers.rb +14 -3
- data/lib/loofah/html/document.rb +1 -0
- data/lib/loofah/html/document_fragment.rb +1 -0
- data/lib/loofah/html5/libxml2_workarounds.rb +1 -0
- data/lib/loofah/html5/safelist.rb +798 -0
- data/lib/loofah/html5/scrub.rb +15 -16
- data/lib/loofah/instance_methods.rb +1 -0
- data/lib/loofah/metahelpers.rb +1 -0
- data/lib/loofah/scrubber.rb +1 -0
- data/lib/loofah/scrubbers.rb +2 -1
- data/lib/loofah/xml/document.rb +1 -0
- data/lib/loofah/xml/document_fragment.rb +1 -0
- data/test/assets/msword.html +63 -0
- data/test/html5/test_sanitizer.rb +49 -17
- data/test/html5/test_scrub.rb +10 -0
- data/test/integration/test_ad_hoc.rb +48 -86
- data/test/unit/test_helpers.rb +4 -4
- metadata +61 -45
- data/lib/loofah/html5/whitelist.rb +0 -186
data/Rakefile
CHANGED
@@ -1,7 +1,6 @@
|
|
1
|
-
require
|
2
|
-
|
3
|
-
require
|
4
|
-
require 'concourse'
|
1
|
+
require "rubygems"
|
2
|
+
require "hoe"
|
3
|
+
require "concourse"
|
5
4
|
|
6
5
|
Hoe.plugin :git
|
7
6
|
Hoe.plugin :gemspec
|
@@ -13,22 +12,23 @@ Hoe.spec "loofah" do
|
|
13
12
|
developer "Bryan Helmkamp", "bryan@brynary.com"
|
14
13
|
|
15
14
|
self.extra_rdoc_files = FileList["*.md"]
|
16
|
-
self.history_file
|
17
|
-
self.readme_file
|
18
|
-
self.license
|
15
|
+
self.history_file = "CHANGELOG.md"
|
16
|
+
self.readme_file = "README.md"
|
17
|
+
self.license "MIT"
|
19
18
|
|
20
|
-
extra_deps
|
21
|
-
extra_deps
|
19
|
+
extra_deps << ["nokogiri", ">=1.5.9"]
|
20
|
+
extra_deps << ["crass", "~> 1.0.2"]
|
22
21
|
|
23
|
-
extra_dev_deps << ["rake", "
|
22
|
+
extra_dev_deps << ["rake", "~> 12.3"]
|
24
23
|
extra_dev_deps << ["minitest", "~>2.2"]
|
25
24
|
extra_dev_deps << ["rr", "~>1.2.0"]
|
26
|
-
extra_dev_deps << ["json", "
|
27
|
-
extra_dev_deps << ["hoe-gemspec", "
|
28
|
-
extra_dev_deps << ["hoe-debugging", "
|
29
|
-
extra_dev_deps << ["hoe-bundler", "
|
30
|
-
extra_dev_deps << ["hoe-git", "
|
31
|
-
extra_dev_deps << ["concourse", ">=0.
|
25
|
+
extra_dev_deps << ["json", "~> 2.2.0"]
|
26
|
+
extra_dev_deps << ["hoe-gemspec", "~> 1.0"]
|
27
|
+
extra_dev_deps << ["hoe-debugging", "~> 2.0"]
|
28
|
+
extra_dev_deps << ["hoe-bundler", "~> 1.5"]
|
29
|
+
extra_dev_deps << ["hoe-git", "~> 1.6"]
|
30
|
+
extra_dev_deps << ["concourse", ">=0.26.0"]
|
31
|
+
extra_dev_deps << ["rubocop", ">=0.76.0"]
|
32
32
|
end
|
33
33
|
|
34
34
|
task :gemspec do
|
@@ -71,9 +71,21 @@ task :doc_upload_to_rubyforge => :docs do
|
|
71
71
|
end
|
72
72
|
end
|
73
73
|
|
74
|
-
desc "generate
|
75
|
-
task :
|
76
|
-
load "tasks/generate-
|
74
|
+
desc "generate safelists from W3C specifications"
|
75
|
+
task :generate_safelists do
|
76
|
+
load "tasks/generate-safelists"
|
77
77
|
end
|
78
78
|
|
79
|
-
|
79
|
+
task :rubocop => [:rubocop_security, :rubocop_frozen_string_literals]
|
80
|
+
task :rubocop_security do
|
81
|
+
sh "rubocop lib --only Security"
|
82
|
+
end
|
83
|
+
task :rubocop_frozen_string_literals do
|
84
|
+
sh "rubocop lib --auto-correct --only Style/FrozenStringLiteralComment"
|
85
|
+
end
|
86
|
+
Rake::Task[:test].prerequisites << :rubocop
|
87
|
+
|
88
|
+
Concourse.new("loofah", fly_target: "ci") do |c|
|
89
|
+
c.add_pipeline "loofah", "loofah.yml"
|
90
|
+
c.add_pipeline "loofah-pr", "loofah-pr.yml"
|
91
|
+
end
|
data/SECURITY.md
CHANGED
@@ -9,7 +9,7 @@ Your report will be acknowledged within 24 hours, and you'll receive a more deta
|
|
9
9
|
If you have not received a reply to your submission within 48 hours, there are a few steps you can take:
|
10
10
|
|
11
11
|
* Contact the current security coordinator (Mike Dalessio <mike.dalessio@gmail.com>)
|
12
|
-
* Email the Loofah user group at loofah@
|
12
|
+
* Email the Loofah user group at loofah-talk@googlegroups.com (archive at https://groups.google.com/forum/#!forum/loofah-talk)
|
13
13
|
|
14
14
|
Please note, the user group list is a public area. When escalating in that venue, please do not discuss your issue. Simply say that you're trying to get a hold of someone from the core team.
|
15
15
|
|
data/lib/loofah.rb
CHANGED
@@ -1,22 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
$LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__))) unless $LOAD_PATH.include?(File.expand_path(File.dirname(__FILE__)))
|
2
3
|
|
3
|
-
require
|
4
|
+
require "nokogiri"
|
4
5
|
|
5
|
-
require
|
6
|
-
require
|
6
|
+
require "loofah/metahelpers"
|
7
|
+
require "loofah/elements"
|
7
8
|
|
8
|
-
require
|
9
|
-
require
|
10
|
-
require
|
9
|
+
require "loofah/html5/safelist"
|
10
|
+
require "loofah/html5/libxml2_workarounds"
|
11
|
+
require "loofah/html5/scrub"
|
11
12
|
|
12
|
-
require
|
13
|
-
require
|
13
|
+
require "loofah/scrubber"
|
14
|
+
require "loofah/scrubbers"
|
14
15
|
|
15
|
-
require
|
16
|
-
require
|
17
|
-
require
|
18
|
-
require
|
19
|
-
require
|
16
|
+
require "loofah/instance_methods"
|
17
|
+
require "loofah/xml/document"
|
18
|
+
require "loofah/xml/document_fragment"
|
19
|
+
require "loofah/html/document"
|
20
|
+
require "loofah/html/document_fragment"
|
20
21
|
|
21
22
|
# == Strings and IO Objects as Input
|
22
23
|
#
|
@@ -28,7 +29,7 @@ require 'loofah/html/document_fragment'
|
|
28
29
|
#
|
29
30
|
module Loofah
|
30
31
|
# The version of Loofah you are using
|
31
|
-
VERSION =
|
32
|
+
VERSION = "2.4.0"
|
32
33
|
|
33
34
|
class << self
|
34
35
|
# Shortcut for Loofah::HTML::Document.parse
|
@@ -77,7 +78,7 @@ module Loofah
|
|
77
78
|
|
78
79
|
# A helper to remove extraneous whitespace from text-ified HTML
|
79
80
|
def remove_extraneous_whitespace(string)
|
80
|
-
string.gsub(/\n\s*\n\s*\n/,"\n\n")
|
81
|
+
string.gsub(/\n\s*\n\s*\n/, "\n\n")
|
81
82
|
end
|
82
83
|
end
|
83
84
|
end
|
data/lib/loofah/elements.rb
CHANGED
data/lib/loofah/helpers.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module Loofah
|
2
3
|
module Helpers
|
3
4
|
class << self
|
@@ -46,8 +47,13 @@ module Loofah
|
|
46
47
|
@full_sanitizer ||= ::Loofah::Helpers::ActionView::FullSanitizer.new
|
47
48
|
end
|
48
49
|
|
50
|
+
def safe_list_sanitizer
|
51
|
+
@safe_list_sanitizer ||= ::Loofah::Helpers::ActionView::SafeListSanitizer.new
|
52
|
+
end
|
53
|
+
|
49
54
|
def white_list_sanitizer
|
50
|
-
|
55
|
+
warn "warning: white_list_sanitizer is deprecated, please use safe_list_sanitizer instead."
|
56
|
+
safe_list_sanitizer
|
51
57
|
end
|
52
58
|
end
|
53
59
|
|
@@ -73,13 +79,13 @@ module Loofah
|
|
73
79
|
#
|
74
80
|
# To use by default, call this in an application initializer:
|
75
81
|
#
|
76
|
-
# ActionView::Helpers::SanitizeHelper.
|
82
|
+
# ActionView::Helpers::SanitizeHelper.safe_list_sanitizer = ::Loofah::Helpers::ActionView::SafeListSanitizer.new
|
77
83
|
#
|
78
84
|
# Or, to generally opt-in to Loofah's view sanitizers:
|
79
85
|
#
|
80
86
|
# Loofah::Helpers::ActionView.set_as_default_sanitizer
|
81
87
|
#
|
82
|
-
class
|
88
|
+
class SafeListSanitizer
|
83
89
|
def sanitize html, *args
|
84
90
|
Loofah::Helpers.sanitize html
|
85
91
|
end
|
@@ -88,6 +94,11 @@ module Loofah
|
|
88
94
|
Loofah::Helpers.sanitize_css style_string
|
89
95
|
end
|
90
96
|
end
|
97
|
+
|
98
|
+
WhiteListSanitizer = SafeListSanitizer
|
99
|
+
if Object.respond_to?(:deprecate_constant)
|
100
|
+
deprecate_constant :WhiteListSanitizer
|
101
|
+
end
|
91
102
|
end
|
92
103
|
end
|
93
104
|
end
|
data/lib/loofah/html/document.rb
CHANGED
@@ -0,0 +1,798 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require "set"
|
3
|
+
|
4
|
+
module Loofah
|
5
|
+
module HTML5 # :nodoc:
|
6
|
+
#
|
7
|
+
# HTML safelist lifted from HTML5lib sanitizer code:
|
8
|
+
#
|
9
|
+
# http://code.google.com/p/html5lib/
|
10
|
+
#
|
11
|
+
# <html5_license>
|
12
|
+
#
|
13
|
+
# Copyright (c) 2006-2008 The Authors
|
14
|
+
#
|
15
|
+
# Contributors:
|
16
|
+
# James Graham - jg307@cam.ac.uk
|
17
|
+
# Anne van Kesteren - annevankesteren@gmail.com
|
18
|
+
# Lachlan Hunt - lachlan.hunt@lachy.id.au
|
19
|
+
# Matt McDonald - kanashii@kanashii.ca
|
20
|
+
# Sam Ruby - rubys@intertwingly.net
|
21
|
+
# Ian Hickson (Google) - ian@hixie.ch
|
22
|
+
# Thomas Broyer - t.broyer@ltgt.net
|
23
|
+
# Jacques Distler - distler@golem.ph.utexas.edu
|
24
|
+
# Henri Sivonen - hsivonen@iki.fi
|
25
|
+
# The Mozilla Foundation (contributions from Henri Sivonen since 2008)
|
26
|
+
#
|
27
|
+
# Permission is hereby granted, free of charge, to any person
|
28
|
+
# obtaining a copy of this software and associated documentation
|
29
|
+
# files (the "Software"), to deal in the Software without
|
30
|
+
# restriction, including without limitation the rights to use, copy,
|
31
|
+
# modify, merge, publish, distribute, sublicense, and/or sell copies
|
32
|
+
# of the Software, and to permit persons to whom the Software is
|
33
|
+
# furnished to do so, subject to the following conditions:
|
34
|
+
#
|
35
|
+
# The above copyright notice and this permission notice shall be
|
36
|
+
# included in all copies or substantial portions of the Software.
|
37
|
+
#
|
38
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
39
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
40
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
41
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
42
|
+
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
43
|
+
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
44
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
45
|
+
# DEALINGS IN THE SOFTWARE.
|
46
|
+
#
|
47
|
+
# </html5_license>
|
48
|
+
module SafeList
|
49
|
+
ACCEPTABLE_ELEMENTS = Set.new([
|
50
|
+
"a",
|
51
|
+
"abbr",
|
52
|
+
"acronym",
|
53
|
+
"address",
|
54
|
+
"area",
|
55
|
+
"article",
|
56
|
+
"aside",
|
57
|
+
"audio",
|
58
|
+
"b",
|
59
|
+
"bdi",
|
60
|
+
"bdo",
|
61
|
+
"big",
|
62
|
+
"blockquote",
|
63
|
+
"br",
|
64
|
+
"button",
|
65
|
+
"canvas",
|
66
|
+
"caption",
|
67
|
+
"center",
|
68
|
+
"cite",
|
69
|
+
"code",
|
70
|
+
"col",
|
71
|
+
"colgroup",
|
72
|
+
"command",
|
73
|
+
"datalist",
|
74
|
+
"dd",
|
75
|
+
"del",
|
76
|
+
"details",
|
77
|
+
"dfn",
|
78
|
+
"dir",
|
79
|
+
"div",
|
80
|
+
"dl",
|
81
|
+
"dt",
|
82
|
+
"em",
|
83
|
+
"fieldset",
|
84
|
+
"figcaption",
|
85
|
+
"figure",
|
86
|
+
"font",
|
87
|
+
"footer",
|
88
|
+
"form",
|
89
|
+
"h1",
|
90
|
+
"h2",
|
91
|
+
"h3",
|
92
|
+
"h4",
|
93
|
+
"h5",
|
94
|
+
"h6",
|
95
|
+
"header",
|
96
|
+
"hr",
|
97
|
+
"i",
|
98
|
+
"img",
|
99
|
+
"input",
|
100
|
+
"ins",
|
101
|
+
"kbd",
|
102
|
+
"label",
|
103
|
+
"legend",
|
104
|
+
"li",
|
105
|
+
"main",
|
106
|
+
"map",
|
107
|
+
"mark",
|
108
|
+
"menu",
|
109
|
+
"meter",
|
110
|
+
"nav",
|
111
|
+
"ol",
|
112
|
+
"optgroup",
|
113
|
+
"option",
|
114
|
+
"output",
|
115
|
+
"p",
|
116
|
+
"pre",
|
117
|
+
"q",
|
118
|
+
"s",
|
119
|
+
"samp",
|
120
|
+
"section",
|
121
|
+
"select",
|
122
|
+
"small",
|
123
|
+
"span",
|
124
|
+
"strike",
|
125
|
+
"strong",
|
126
|
+
"sub",
|
127
|
+
"summary",
|
128
|
+
"sup",
|
129
|
+
"table",
|
130
|
+
"tbody",
|
131
|
+
"td",
|
132
|
+
"textarea",
|
133
|
+
"tfoot",
|
134
|
+
"th",
|
135
|
+
"thead",
|
136
|
+
"time",
|
137
|
+
"tr",
|
138
|
+
"tt",
|
139
|
+
"u",
|
140
|
+
"ul",
|
141
|
+
"var",
|
142
|
+
"video",
|
143
|
+
])
|
144
|
+
|
145
|
+
MATHML_ELEMENTS = Set.new([
|
146
|
+
"annotation",
|
147
|
+
"annotation-xml",
|
148
|
+
"maction",
|
149
|
+
"math",
|
150
|
+
"merror",
|
151
|
+
"mfenced",
|
152
|
+
"mfrac",
|
153
|
+
"mi",
|
154
|
+
"mmultiscripts",
|
155
|
+
"mn",
|
156
|
+
"mo",
|
157
|
+
"mover",
|
158
|
+
"mpadded",
|
159
|
+
"mphantom",
|
160
|
+
"mprescripts",
|
161
|
+
"mroot",
|
162
|
+
"mrow",
|
163
|
+
"mspace",
|
164
|
+
"msqrt",
|
165
|
+
"mstyle",
|
166
|
+
"msub",
|
167
|
+
"msubsup",
|
168
|
+
"msup",
|
169
|
+
"mtable",
|
170
|
+
"mtd",
|
171
|
+
"mtext",
|
172
|
+
"mtr",
|
173
|
+
"munder",
|
174
|
+
"munderover",
|
175
|
+
"none",
|
176
|
+
"semantics",
|
177
|
+
])
|
178
|
+
|
179
|
+
SVG_ELEMENTS = Set.new([
|
180
|
+
"a",
|
181
|
+
"animate",
|
182
|
+
"animateColor",
|
183
|
+
"animateMotion",
|
184
|
+
"animateTransform",
|
185
|
+
"circle",
|
186
|
+
"clipPath",
|
187
|
+
"defs",
|
188
|
+
"desc",
|
189
|
+
"ellipse",
|
190
|
+
"feGaussianBlur",
|
191
|
+
"filter",
|
192
|
+
"font-face",
|
193
|
+
"font-face-name",
|
194
|
+
"font-face-src",
|
195
|
+
"foreignObject",
|
196
|
+
"g",
|
197
|
+
"glyph",
|
198
|
+
"hkern",
|
199
|
+
"line",
|
200
|
+
"linearGradient",
|
201
|
+
"marker",
|
202
|
+
"mask",
|
203
|
+
"metadata",
|
204
|
+
"missing-glyph",
|
205
|
+
"mpath",
|
206
|
+
"path",
|
207
|
+
"polygon",
|
208
|
+
"polyline",
|
209
|
+
"radialGradient",
|
210
|
+
"rect",
|
211
|
+
"set",
|
212
|
+
"stop",
|
213
|
+
"svg",
|
214
|
+
"switch",
|
215
|
+
"symbol",
|
216
|
+
"text",
|
217
|
+
"textPath",
|
218
|
+
"title",
|
219
|
+
"tspan",
|
220
|
+
"use",
|
221
|
+
])
|
222
|
+
|
223
|
+
ACCEPTABLE_ATTRIBUTES = Set.new([
|
224
|
+
"abbr",
|
225
|
+
"accept",
|
226
|
+
"accept-charset",
|
227
|
+
"accesskey",
|
228
|
+
"action",
|
229
|
+
"align",
|
230
|
+
"alt",
|
231
|
+
"axis",
|
232
|
+
"border",
|
233
|
+
"cellpadding",
|
234
|
+
"cellspacing",
|
235
|
+
"char",
|
236
|
+
"charoff",
|
237
|
+
"charset",
|
238
|
+
"checked",
|
239
|
+
"cite",
|
240
|
+
"class",
|
241
|
+
"clear",
|
242
|
+
"color",
|
243
|
+
"cols",
|
244
|
+
"colspan",
|
245
|
+
"compact",
|
246
|
+
"contenteditable",
|
247
|
+
"coords",
|
248
|
+
"datetime",
|
249
|
+
"dir",
|
250
|
+
"disabled",
|
251
|
+
"enctype",
|
252
|
+
"for",
|
253
|
+
"frame",
|
254
|
+
"headers",
|
255
|
+
"height",
|
256
|
+
"href",
|
257
|
+
"hreflang",
|
258
|
+
"hspace",
|
259
|
+
"id",
|
260
|
+
"ismap",
|
261
|
+
"label",
|
262
|
+
"lang",
|
263
|
+
"longdesc",
|
264
|
+
"loop",
|
265
|
+
"loopcount",
|
266
|
+
"loopend",
|
267
|
+
"loopstart",
|
268
|
+
"maxlength",
|
269
|
+
"media",
|
270
|
+
"method",
|
271
|
+
"multiple",
|
272
|
+
"name",
|
273
|
+
"nohref",
|
274
|
+
"noshade",
|
275
|
+
"nowrap",
|
276
|
+
"poster",
|
277
|
+
"preload",
|
278
|
+
"prompt",
|
279
|
+
"readonly",
|
280
|
+
"rel",
|
281
|
+
"rev",
|
282
|
+
"rows",
|
283
|
+
"rowspan",
|
284
|
+
"rules",
|
285
|
+
"scope",
|
286
|
+
"selected",
|
287
|
+
"shape",
|
288
|
+
"size",
|
289
|
+
"span",
|
290
|
+
"src",
|
291
|
+
"start",
|
292
|
+
"style",
|
293
|
+
"summary",
|
294
|
+
"tabindex",
|
295
|
+
"target",
|
296
|
+
"title",
|
297
|
+
"type",
|
298
|
+
"usemap",
|
299
|
+
"valign",
|
300
|
+
"value",
|
301
|
+
"vspace",
|
302
|
+
"width",
|
303
|
+
"xml:lang",
|
304
|
+
])
|
305
|
+
|
306
|
+
MATHML_ATTRIBUTES = Set.new([
|
307
|
+
"actiontype",
|
308
|
+
"align",
|
309
|
+
"close",
|
310
|
+
"columnalign",
|
311
|
+
"columnlines",
|
312
|
+
"columnspacing",
|
313
|
+
"columnspan",
|
314
|
+
"depth",
|
315
|
+
"display",
|
316
|
+
"displaystyle",
|
317
|
+
"encoding",
|
318
|
+
"equalcolumns",
|
319
|
+
"equalrows",
|
320
|
+
"fence",
|
321
|
+
"fontstyle",
|
322
|
+
"fontweight",
|
323
|
+
"frame",
|
324
|
+
"height",
|
325
|
+
"linethickness",
|
326
|
+
"lspace",
|
327
|
+
"mathbackground",
|
328
|
+
"mathcolor",
|
329
|
+
"mathvariant",
|
330
|
+
"maxsize",
|
331
|
+
"minsize",
|
332
|
+
"open",
|
333
|
+
"other",
|
334
|
+
"rowalign",
|
335
|
+
"rowlines",
|
336
|
+
"rowspacing",
|
337
|
+
"rowspan",
|
338
|
+
"rspace",
|
339
|
+
"scriptlevel",
|
340
|
+
"selection",
|
341
|
+
"separator",
|
342
|
+
"separators",
|
343
|
+
"stretchy",
|
344
|
+
"width",
|
345
|
+
"xlink:href",
|
346
|
+
"xlink:show",
|
347
|
+
"xlink:type",
|
348
|
+
"xmlns",
|
349
|
+
"xmlns:xlink",
|
350
|
+
])
|
351
|
+
|
352
|
+
SVG_ATTRIBUTES = Set.new([
|
353
|
+
"accent-height",
|
354
|
+
"accumulate",
|
355
|
+
"additive",
|
356
|
+
"alphabetic",
|
357
|
+
"arabic-form",
|
358
|
+
"ascent",
|
359
|
+
"attributeName",
|
360
|
+
"attributeType",
|
361
|
+
"baseProfile",
|
362
|
+
"bbox",
|
363
|
+
"begin",
|
364
|
+
"calcMode",
|
365
|
+
"cap-height",
|
366
|
+
"class",
|
367
|
+
"clip-path",
|
368
|
+
"clip-rule",
|
369
|
+
"color",
|
370
|
+
"color-interpolation-filters",
|
371
|
+
"color-rendering",
|
372
|
+
"content",
|
373
|
+
"cx",
|
374
|
+
"cy",
|
375
|
+
"d",
|
376
|
+
"descent",
|
377
|
+
"display",
|
378
|
+
"dur",
|
379
|
+
"dx",
|
380
|
+
"dy",
|
381
|
+
"end",
|
382
|
+
"fill",
|
383
|
+
"fill-opacity",
|
384
|
+
"fill-rule",
|
385
|
+
"filterRes",
|
386
|
+
"filterUnits",
|
387
|
+
"font-family",
|
388
|
+
"font-size",
|
389
|
+
"font-stretch",
|
390
|
+
"font-style",
|
391
|
+
"font-variant",
|
392
|
+
"font-weight",
|
393
|
+
"fx",
|
394
|
+
"fy",
|
395
|
+
"g1",
|
396
|
+
"g2",
|
397
|
+
"glyph-name",
|
398
|
+
"gradientUnits",
|
399
|
+
"hanging",
|
400
|
+
"height",
|
401
|
+
"horiz-adv-x",
|
402
|
+
"horiz-origin-x",
|
403
|
+
"id",
|
404
|
+
"ideographic",
|
405
|
+
"k",
|
406
|
+
"keyPoints",
|
407
|
+
"keySplines",
|
408
|
+
"keyTimes",
|
409
|
+
"lang",
|
410
|
+
"marker-end",
|
411
|
+
"marker-mid",
|
412
|
+
"marker-start",
|
413
|
+
"markerHeight",
|
414
|
+
"markerUnits",
|
415
|
+
"markerWidth",
|
416
|
+
"maskContentUnits",
|
417
|
+
"maskUnits",
|
418
|
+
"mathematical",
|
419
|
+
"max",
|
420
|
+
"method",
|
421
|
+
"min",
|
422
|
+
"name",
|
423
|
+
"offset",
|
424
|
+
"opacity",
|
425
|
+
"orient",
|
426
|
+
"origin",
|
427
|
+
"overline-position",
|
428
|
+
"overline-thickness",
|
429
|
+
"panose-1",
|
430
|
+
"path",
|
431
|
+
"pathLength",
|
432
|
+
"patternContentUnits",
|
433
|
+
"patternTransform",
|
434
|
+
"patternUnits",
|
435
|
+
"points",
|
436
|
+
"preserveAspectRatio",
|
437
|
+
"primitiveUnits",
|
438
|
+
"r",
|
439
|
+
"refX",
|
440
|
+
"refY",
|
441
|
+
"repeatCount",
|
442
|
+
"repeatDur",
|
443
|
+
"requiredExtensions",
|
444
|
+
"requiredFeatures",
|
445
|
+
"restart",
|
446
|
+
"rotate",
|
447
|
+
"rx",
|
448
|
+
"ry",
|
449
|
+
"slope",
|
450
|
+
"spacing",
|
451
|
+
"startOffset",
|
452
|
+
"stdDeviation",
|
453
|
+
"stemh",
|
454
|
+
"stemv",
|
455
|
+
"stop-color",
|
456
|
+
"stop-opacity",
|
457
|
+
"strikethrough-position",
|
458
|
+
"strikethrough-thickness",
|
459
|
+
"stroke",
|
460
|
+
"stroke-dasharray",
|
461
|
+
"stroke-dashoffset",
|
462
|
+
"stroke-linecap",
|
463
|
+
"stroke-linejoin",
|
464
|
+
"stroke-miterlimit",
|
465
|
+
"stroke-opacity",
|
466
|
+
"stroke-width",
|
467
|
+
"systemLanguage",
|
468
|
+
"target",
|
469
|
+
"text-anchor",
|
470
|
+
"transform",
|
471
|
+
"type",
|
472
|
+
"u1",
|
473
|
+
"u2",
|
474
|
+
"underline-position",
|
475
|
+
"underline-thickness",
|
476
|
+
"unicode",
|
477
|
+
"unicode-range",
|
478
|
+
"units-per-em",
|
479
|
+
"version",
|
480
|
+
"viewBox",
|
481
|
+
"visibility",
|
482
|
+
"width",
|
483
|
+
"widths",
|
484
|
+
"x",
|
485
|
+
"x-height",
|
486
|
+
"x1",
|
487
|
+
"x2",
|
488
|
+
"xlink:actuate",
|
489
|
+
"xlink:arcrole",
|
490
|
+
"xlink:href",
|
491
|
+
"xlink:role",
|
492
|
+
"xlink:show",
|
493
|
+
"xlink:title",
|
494
|
+
"xlink:type",
|
495
|
+
"xml:base",
|
496
|
+
"xml:lang",
|
497
|
+
"xml:space",
|
498
|
+
"xmlns",
|
499
|
+
"xmlns:xlink",
|
500
|
+
"y",
|
501
|
+
"y1",
|
502
|
+
"y2",
|
503
|
+
"zoomAndPan",
|
504
|
+
])
|
505
|
+
|
506
|
+
ATTR_VAL_IS_URI = Set.new([
|
507
|
+
"action",
|
508
|
+
"cite",
|
509
|
+
"href",
|
510
|
+
"longdesc",
|
511
|
+
"poster",
|
512
|
+
"preload",
|
513
|
+
"src",
|
514
|
+
"xlink:href",
|
515
|
+
"xml:base",
|
516
|
+
])
|
517
|
+
|
518
|
+
SVG_ATTR_VAL_ALLOWS_REF = Set.new([
|
519
|
+
"clip-path",
|
520
|
+
"color-profile",
|
521
|
+
"cursor",
|
522
|
+
"fill",
|
523
|
+
"filter",
|
524
|
+
"marker",
|
525
|
+
"marker-end",
|
526
|
+
"marker-mid",
|
527
|
+
"marker-start",
|
528
|
+
"mask",
|
529
|
+
"stroke",
|
530
|
+
])
|
531
|
+
|
532
|
+
SVG_ALLOW_LOCAL_HREF = Set.new([
|
533
|
+
"altGlyph",
|
534
|
+
"animate",
|
535
|
+
"animateColor",
|
536
|
+
"animateMotion",
|
537
|
+
"animateTransform",
|
538
|
+
"cursor",
|
539
|
+
"feImage",
|
540
|
+
"filter",
|
541
|
+
"linearGradient",
|
542
|
+
"pattern",
|
543
|
+
"radialGradient",
|
544
|
+
"set",
|
545
|
+
"textpath",
|
546
|
+
"tref",
|
547
|
+
"use",
|
548
|
+
])
|
549
|
+
|
550
|
+
ACCEPTABLE_CSS_PROPERTIES = Set.new([
|
551
|
+
"azimuth",
|
552
|
+
"background-color",
|
553
|
+
"border-bottom-color",
|
554
|
+
"border-collapse",
|
555
|
+
"border-color",
|
556
|
+
"border-left-color",
|
557
|
+
"border-right-color",
|
558
|
+
"border-top-color",
|
559
|
+
"clear",
|
560
|
+
"color",
|
561
|
+
"cursor",
|
562
|
+
"direction",
|
563
|
+
"display",
|
564
|
+
"elevation",
|
565
|
+
"float",
|
566
|
+
"font",
|
567
|
+
"font-family",
|
568
|
+
"font-size",
|
569
|
+
"font-style",
|
570
|
+
"font-variant",
|
571
|
+
"font-weight",
|
572
|
+
"height",
|
573
|
+
"letter-spacing",
|
574
|
+
"line-height",
|
575
|
+
"list-style",
|
576
|
+
"list-style-type",
|
577
|
+
"max-width",
|
578
|
+
"overflow",
|
579
|
+
"pause",
|
580
|
+
"pause-after",
|
581
|
+
"pause-before",
|
582
|
+
"pitch",
|
583
|
+
"pitch-range",
|
584
|
+
"richness",
|
585
|
+
"speak",
|
586
|
+
"speak-header",
|
587
|
+
"speak-numeral",
|
588
|
+
"speak-punctuation",
|
589
|
+
"speech-rate",
|
590
|
+
"stress",
|
591
|
+
"text-align",
|
592
|
+
"text-decoration",
|
593
|
+
"text-indent",
|
594
|
+
"unicode-bidi",
|
595
|
+
"vertical-align",
|
596
|
+
"voice-family",
|
597
|
+
"volume",
|
598
|
+
"white-space",
|
599
|
+
"width",
|
600
|
+
])
|
601
|
+
|
602
|
+
ACCEPTABLE_CSS_KEYWORDS = Set.new([
|
603
|
+
"!important",
|
604
|
+
"aqua",
|
605
|
+
"auto",
|
606
|
+
"black",
|
607
|
+
"block",
|
608
|
+
"blue",
|
609
|
+
"bold",
|
610
|
+
"both",
|
611
|
+
"bottom",
|
612
|
+
"brown",
|
613
|
+
"center",
|
614
|
+
"collapse",
|
615
|
+
"dashed",
|
616
|
+
"dotted",
|
617
|
+
"fuchsia",
|
618
|
+
"gray",
|
619
|
+
"green",
|
620
|
+
"italic",
|
621
|
+
"left",
|
622
|
+
"lime",
|
623
|
+
"maroon",
|
624
|
+
"medium",
|
625
|
+
"navy",
|
626
|
+
"none",
|
627
|
+
"normal",
|
628
|
+
"nowrap",
|
629
|
+
"olive",
|
630
|
+
"pointer",
|
631
|
+
"purple",
|
632
|
+
"red",
|
633
|
+
"right",
|
634
|
+
"silver",
|
635
|
+
"solid",
|
636
|
+
"teal",
|
637
|
+
"thin",
|
638
|
+
"thick",
|
639
|
+
"top",
|
640
|
+
"transparent",
|
641
|
+
"underline",
|
642
|
+
"white",
|
643
|
+
"yellow",
|
644
|
+
])
|
645
|
+
|
646
|
+
# see https://www.quackit.com/css/functions/
|
647
|
+
# omit `url` and `image` from that list
|
648
|
+
ACCEPTABLE_CSS_FUNCTIONS = Set.new([
|
649
|
+
"attr",
|
650
|
+
"blur",
|
651
|
+
"brightness",
|
652
|
+
"calc",
|
653
|
+
"circle",
|
654
|
+
"contrast",
|
655
|
+
"counter",
|
656
|
+
"counters",
|
657
|
+
"cubic-bezier",
|
658
|
+
"drop-shadow",
|
659
|
+
"ellipse",
|
660
|
+
"grayscale",
|
661
|
+
"hsl",
|
662
|
+
"hsla",
|
663
|
+
"hue-rotate",
|
664
|
+
"hwb",
|
665
|
+
"inset",
|
666
|
+
"invert",
|
667
|
+
"linear-gradient",
|
668
|
+
"matrix",
|
669
|
+
"matrix3d",
|
670
|
+
"opacity",
|
671
|
+
"perspective",
|
672
|
+
"polygon",
|
673
|
+
"radial-gradient",
|
674
|
+
"repeating-linear-gradient",
|
675
|
+
"repeating-radial-gradient",
|
676
|
+
"rgb",
|
677
|
+
"rgba",
|
678
|
+
"rotate",
|
679
|
+
"rotate3d",
|
680
|
+
"rotateX",
|
681
|
+
"rotateY",
|
682
|
+
"rotateZ",
|
683
|
+
"saturate",
|
684
|
+
"sepia",
|
685
|
+
"scale",
|
686
|
+
"scale3d",
|
687
|
+
"scaleX",
|
688
|
+
"scaleY",
|
689
|
+
"scaleZ",
|
690
|
+
"skew",
|
691
|
+
"skewX",
|
692
|
+
"skewY",
|
693
|
+
"symbols",
|
694
|
+
"translate",
|
695
|
+
"translate3d",
|
696
|
+
"translateX",
|
697
|
+
"translateY",
|
698
|
+
"translateZ",
|
699
|
+
])
|
700
|
+
|
701
|
+
SHORTHAND_CSS_PROPERTIES = Set.new([
|
702
|
+
"background",
|
703
|
+
"border",
|
704
|
+
"margin",
|
705
|
+
"padding",
|
706
|
+
])
|
707
|
+
|
708
|
+
ACCEPTABLE_SVG_PROPERTIES = Set.new([
|
709
|
+
"fill",
|
710
|
+
"fill-opacity",
|
711
|
+
"fill-rule",
|
712
|
+
"stroke",
|
713
|
+
"stroke-width",
|
714
|
+
"stroke-linecap",
|
715
|
+
"stroke-linejoin",
|
716
|
+
"stroke-opacity",
|
717
|
+
])
|
718
|
+
|
719
|
+
PROTOCOL_SEPARATOR = /:|(�*58)|(p)|(�*3a)|(%|%)3A/i
|
720
|
+
|
721
|
+
ACCEPTABLE_PROTOCOLS = Set.new([
|
722
|
+
"afs",
|
723
|
+
"aim",
|
724
|
+
"callto",
|
725
|
+
"data",
|
726
|
+
"ed2k",
|
727
|
+
"feed",
|
728
|
+
"ftp",
|
729
|
+
"gopher",
|
730
|
+
"http",
|
731
|
+
"https",
|
732
|
+
"irc",
|
733
|
+
"line",
|
734
|
+
"mailto",
|
735
|
+
"news",
|
736
|
+
"nntp",
|
737
|
+
"rsync",
|
738
|
+
"rtsp",
|
739
|
+
"sftp",
|
740
|
+
"ssh",
|
741
|
+
"tag",
|
742
|
+
"tel",
|
743
|
+
"telnet",
|
744
|
+
"urn",
|
745
|
+
"webcal",
|
746
|
+
"xmpp",
|
747
|
+
])
|
748
|
+
|
749
|
+
ACCEPTABLE_URI_DATA_MEDIATYPES = Set.new([
|
750
|
+
"image/gif",
|
751
|
+
"image/jpeg",
|
752
|
+
"image/png",
|
753
|
+
"image/svg+xml",
|
754
|
+
"text/css",
|
755
|
+
"text/plain",
|
756
|
+
])
|
757
|
+
|
758
|
+
# subclasses may define their own versions of these constants
|
759
|
+
ALLOWED_ELEMENTS = ACCEPTABLE_ELEMENTS + MATHML_ELEMENTS + SVG_ELEMENTS
|
760
|
+
ALLOWED_ATTRIBUTES = ACCEPTABLE_ATTRIBUTES + MATHML_ATTRIBUTES + SVG_ATTRIBUTES
|
761
|
+
ALLOWED_CSS_PROPERTIES = ACCEPTABLE_CSS_PROPERTIES
|
762
|
+
ALLOWED_CSS_KEYWORDS = ACCEPTABLE_CSS_KEYWORDS
|
763
|
+
ALLOWED_CSS_FUNCTIONS = ACCEPTABLE_CSS_FUNCTIONS
|
764
|
+
ALLOWED_SVG_PROPERTIES = ACCEPTABLE_SVG_PROPERTIES
|
765
|
+
ALLOWED_PROTOCOLS = ACCEPTABLE_PROTOCOLS
|
766
|
+
ALLOWED_URI_DATA_MEDIATYPES = ACCEPTABLE_URI_DATA_MEDIATYPES
|
767
|
+
|
768
|
+
VOID_ELEMENTS = Set.new([
|
769
|
+
"area",
|
770
|
+
"base",
|
771
|
+
"br",
|
772
|
+
"col",
|
773
|
+
"embed",
|
774
|
+
"hr",
|
775
|
+
"img",
|
776
|
+
"input",
|
777
|
+
"link",
|
778
|
+
"meta",
|
779
|
+
"param",
|
780
|
+
])
|
781
|
+
|
782
|
+
# additional tags we should consider safe since we have libxml2 fixing up our documents.
|
783
|
+
TAGS_SAFE_WITH_LIBXML2 = Set.new([
|
784
|
+
"body",
|
785
|
+
"head",
|
786
|
+
"html",
|
787
|
+
])
|
788
|
+
ALLOWED_ELEMENTS_WITH_LIBXML2 = ALLOWED_ELEMENTS + TAGS_SAFE_WITH_LIBXML2
|
789
|
+
end
|
790
|
+
|
791
|
+
WhiteList = SafeList
|
792
|
+
if Object.respond_to?(:deprecate_constant)
|
793
|
+
deprecate_constant :WhiteList
|
794
|
+
end
|
795
|
+
|
796
|
+
::Loofah::MetaHelpers.add_downcased_set_members_to_all_set_constants ::Loofah::HTML5::SafeList
|
797
|
+
end
|
798
|
+
end
|