Line data Source code
1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 : /* This Source Code Form is subject to the terms of the Mozilla Public
4 : * License, v. 2.0. If a copy of the MPL was not distributed with this
5 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 :
7 : #include "nsTreeSanitizer.h"
8 :
9 : #include "mozilla/ArrayUtils.h"
10 : #include "mozilla/StyleSheetInlines.h"
11 : #include "mozilla/css/Declaration.h"
12 : #include "mozilla/css/StyleRule.h"
13 : #include "mozilla/css/Rule.h"
14 : #include "nsCSSParser.h"
15 : #include "nsCSSPropertyID.h"
16 : #include "nsUnicharInputStream.h"
17 : #include "nsIDOMCSSRule.h"
18 : #include "nsAttrName.h"
19 : #include "nsIScriptSecurityManager.h"
20 : #include "nsNetUtil.h"
21 : #include "nsComponentManagerUtils.h"
22 : #include "NullPrincipal.h"
23 : #include "nsContentUtils.h"
24 : #include "nsIParserUtils.h"
25 : #include "nsIDocument.h"
26 : #include "nsQueryObject.h"
27 :
28 : using namespace mozilla;
29 :
30 : //
31 : // Thanks to Mark Pilgrim and Sam Ruby for the initial whitelist
32 : //
33 : nsIAtom** const kElementsHTML[] = {
34 : &nsGkAtoms::a,
35 : &nsGkAtoms::abbr,
36 : &nsGkAtoms::acronym,
37 : &nsGkAtoms::address,
38 : &nsGkAtoms::area,
39 : &nsGkAtoms::article,
40 : &nsGkAtoms::aside,
41 : &nsGkAtoms::audio,
42 : &nsGkAtoms::b,
43 : &nsGkAtoms::bdi,
44 : &nsGkAtoms::bdo,
45 : &nsGkAtoms::big,
46 : &nsGkAtoms::blockquote,
47 : // body checked specially
48 : &nsGkAtoms::br,
49 : &nsGkAtoms::button,
50 : &nsGkAtoms::canvas,
51 : &nsGkAtoms::caption,
52 : &nsGkAtoms::center,
53 : &nsGkAtoms::cite,
54 : &nsGkAtoms::code,
55 : &nsGkAtoms::col,
56 : &nsGkAtoms::colgroup,
57 : &nsGkAtoms::datalist,
58 : &nsGkAtoms::dd,
59 : &nsGkAtoms::del,
60 : &nsGkAtoms::details,
61 : &nsGkAtoms::dfn,
62 : &nsGkAtoms::dir,
63 : &nsGkAtoms::div,
64 : &nsGkAtoms::dl,
65 : &nsGkAtoms::dt,
66 : &nsGkAtoms::em,
67 : &nsGkAtoms::fieldset,
68 : &nsGkAtoms::figcaption,
69 : &nsGkAtoms::figure,
70 : &nsGkAtoms::font,
71 : &nsGkAtoms::footer,
72 : &nsGkAtoms::form,
73 : &nsGkAtoms::h1,
74 : &nsGkAtoms::h2,
75 : &nsGkAtoms::h3,
76 : &nsGkAtoms::h4,
77 : &nsGkAtoms::h5,
78 : &nsGkAtoms::h6,
79 : // head checked specially
80 : &nsGkAtoms::header,
81 : &nsGkAtoms::hgroup,
82 : &nsGkAtoms::hr,
83 : // html checked specially
84 : &nsGkAtoms::i,
85 : &nsGkAtoms::img,
86 : &nsGkAtoms::input,
87 : &nsGkAtoms::ins,
88 : &nsGkAtoms::kbd,
89 : &nsGkAtoms::label,
90 : &nsGkAtoms::legend,
91 : &nsGkAtoms::li,
92 : &nsGkAtoms::link,
93 : &nsGkAtoms::listing,
94 : &nsGkAtoms::map,
95 : &nsGkAtoms::mark,
96 : &nsGkAtoms::menu,
97 : &nsGkAtoms::meta,
98 : &nsGkAtoms::meter,
99 : &nsGkAtoms::nav,
100 : &nsGkAtoms::nobr,
101 : &nsGkAtoms::noscript,
102 : &nsGkAtoms::ol,
103 : &nsGkAtoms::optgroup,
104 : &nsGkAtoms::option,
105 : &nsGkAtoms::output,
106 : &nsGkAtoms::p,
107 : &nsGkAtoms::pre,
108 : &nsGkAtoms::progress,
109 : &nsGkAtoms::q,
110 : &nsGkAtoms::rb,
111 : &nsGkAtoms::rp,
112 : &nsGkAtoms::rt,
113 : &nsGkAtoms::rtc,
114 : &nsGkAtoms::ruby,
115 : &nsGkAtoms::s,
116 : &nsGkAtoms::samp,
117 : &nsGkAtoms::section,
118 : &nsGkAtoms::select,
119 : &nsGkAtoms::small,
120 : &nsGkAtoms::source,
121 : &nsGkAtoms::span,
122 : &nsGkAtoms::strike,
123 : &nsGkAtoms::strong,
124 : &nsGkAtoms::sub,
125 : &nsGkAtoms::summary,
126 : &nsGkAtoms::sup,
127 : // style checked specially
128 : &nsGkAtoms::table,
129 : &nsGkAtoms::tbody,
130 : &nsGkAtoms::td,
131 : &nsGkAtoms::textarea,
132 : &nsGkAtoms::tfoot,
133 : &nsGkAtoms::th,
134 : &nsGkAtoms::thead,
135 : &nsGkAtoms::time,
136 : // title checked specially
137 : &nsGkAtoms::tr,
138 : &nsGkAtoms::track,
139 : &nsGkAtoms::tt,
140 : &nsGkAtoms::u,
141 : &nsGkAtoms::ul,
142 : &nsGkAtoms::var,
143 : &nsGkAtoms::video,
144 : &nsGkAtoms::wbr,
145 : nullptr
146 : };
147 :
148 : nsIAtom** const kAttributesHTML[] = {
149 : &nsGkAtoms::abbr,
150 : &nsGkAtoms::accept,
151 : &nsGkAtoms::acceptcharset,
152 : &nsGkAtoms::accesskey,
153 : &nsGkAtoms::action,
154 : &nsGkAtoms::alt,
155 : &nsGkAtoms::as,
156 : &nsGkAtoms::autocomplete,
157 : &nsGkAtoms::autofocus,
158 : &nsGkAtoms::autoplay,
159 : &nsGkAtoms::axis,
160 : &nsGkAtoms::_char,
161 : &nsGkAtoms::charoff,
162 : &nsGkAtoms::charset,
163 : &nsGkAtoms::checked,
164 : &nsGkAtoms::cite,
165 : &nsGkAtoms::_class,
166 : &nsGkAtoms::cols,
167 : &nsGkAtoms::colspan,
168 : &nsGkAtoms::content,
169 : &nsGkAtoms::contenteditable,
170 : &nsGkAtoms::contextmenu,
171 : &nsGkAtoms::controls,
172 : &nsGkAtoms::coords,
173 : &nsGkAtoms::datetime,
174 : &nsGkAtoms::dir,
175 : &nsGkAtoms::disabled,
176 : &nsGkAtoms::draggable,
177 : &nsGkAtoms::enctype,
178 : &nsGkAtoms::face,
179 : &nsGkAtoms::_for,
180 : &nsGkAtoms::frame,
181 : &nsGkAtoms::headers,
182 : &nsGkAtoms::height,
183 : &nsGkAtoms::hidden,
184 : &nsGkAtoms::high,
185 : &nsGkAtoms::href,
186 : &nsGkAtoms::hreflang,
187 : &nsGkAtoms::icon,
188 : &nsGkAtoms::id,
189 : &nsGkAtoms::ismap,
190 : &nsGkAtoms::itemid,
191 : &nsGkAtoms::itemprop,
192 : &nsGkAtoms::itemref,
193 : &nsGkAtoms::itemscope,
194 : &nsGkAtoms::itemtype,
195 : &nsGkAtoms::kind,
196 : &nsGkAtoms::label,
197 : &nsGkAtoms::lang,
198 : &nsGkAtoms::list,
199 : &nsGkAtoms::longdesc,
200 : &nsGkAtoms::loop,
201 : &nsGkAtoms::low,
202 : &nsGkAtoms::max,
203 : &nsGkAtoms::maxlength,
204 : &nsGkAtoms::media,
205 : &nsGkAtoms::method,
206 : &nsGkAtoms::min,
207 : &nsGkAtoms::minlength,
208 : &nsGkAtoms::multiple,
209 : &nsGkAtoms::muted,
210 : &nsGkAtoms::name,
211 : &nsGkAtoms::nohref,
212 : &nsGkAtoms::novalidate,
213 : &nsGkAtoms::nowrap,
214 : &nsGkAtoms::open,
215 : &nsGkAtoms::optimum,
216 : &nsGkAtoms::pattern,
217 : &nsGkAtoms::placeholder,
218 : &nsGkAtoms::playbackrate,
219 : &nsGkAtoms::poster,
220 : &nsGkAtoms::preload,
221 : &nsGkAtoms::prompt,
222 : &nsGkAtoms::pubdate,
223 : &nsGkAtoms::radiogroup,
224 : &nsGkAtoms::readonly,
225 : &nsGkAtoms::rel,
226 : &nsGkAtoms::required,
227 : &nsGkAtoms::rev,
228 : &nsGkAtoms::reversed,
229 : &nsGkAtoms::role,
230 : &nsGkAtoms::rows,
231 : &nsGkAtoms::rowspan,
232 : &nsGkAtoms::rules,
233 : &nsGkAtoms::scoped,
234 : &nsGkAtoms::scope,
235 : &nsGkAtoms::selected,
236 : &nsGkAtoms::shape,
237 : &nsGkAtoms::span,
238 : &nsGkAtoms::spellcheck,
239 : &nsGkAtoms::src,
240 : &nsGkAtoms::srclang,
241 : &nsGkAtoms::start,
242 : &nsGkAtoms::summary,
243 : &nsGkAtoms::tabindex,
244 : &nsGkAtoms::target,
245 : &nsGkAtoms::title,
246 : &nsGkAtoms::type,
247 : &nsGkAtoms::usemap,
248 : &nsGkAtoms::value,
249 : &nsGkAtoms::width,
250 : &nsGkAtoms::wrap,
251 : nullptr
252 : };
253 :
254 : nsIAtom** const kPresAttributesHTML[] = {
255 : &nsGkAtoms::align,
256 : &nsGkAtoms::background,
257 : &nsGkAtoms::bgcolor,
258 : &nsGkAtoms::border,
259 : &nsGkAtoms::cellpadding,
260 : &nsGkAtoms::cellspacing,
261 : &nsGkAtoms::color,
262 : &nsGkAtoms::compact,
263 : &nsGkAtoms::clear,
264 : &nsGkAtoms::hspace,
265 : &nsGkAtoms::noshade,
266 : &nsGkAtoms::pointSize,
267 : &nsGkAtoms::size,
268 : &nsGkAtoms::valign,
269 : &nsGkAtoms::vspace,
270 : nullptr
271 : };
272 :
273 : nsIAtom** const kURLAttributesHTML[] = {
274 : &nsGkAtoms::action,
275 : &nsGkAtoms::href,
276 : &nsGkAtoms::src,
277 : &nsGkAtoms::longdesc,
278 : &nsGkAtoms::cite,
279 : &nsGkAtoms::background,
280 : nullptr
281 : };
282 :
283 : nsIAtom** const kElementsSVG[] = {
284 : &nsGkAtoms::a, // a
285 : &nsGkAtoms::circle, // circle
286 : &nsGkAtoms::clipPath, // clipPath
287 : &nsGkAtoms::colorProfile, // color-profile
288 : &nsGkAtoms::cursor, // cursor
289 : &nsGkAtoms::defs, // defs
290 : &nsGkAtoms::desc, // desc
291 : &nsGkAtoms::ellipse, // ellipse
292 : &nsGkAtoms::elevation, // elevation
293 : &nsGkAtoms::erode, // erode
294 : &nsGkAtoms::ex, // ex
295 : &nsGkAtoms::exact, // exact
296 : &nsGkAtoms::exponent, // exponent
297 : &nsGkAtoms::feBlend, // feBlend
298 : &nsGkAtoms::feColorMatrix, // feColorMatrix
299 : &nsGkAtoms::feComponentTransfer, // feComponentTransfer
300 : &nsGkAtoms::feComposite, // feComposite
301 : &nsGkAtoms::feConvolveMatrix, // feConvolveMatrix
302 : &nsGkAtoms::feDiffuseLighting, // feDiffuseLighting
303 : &nsGkAtoms::feDisplacementMap, // feDisplacementMap
304 : &nsGkAtoms::feDistantLight, // feDistantLight
305 : &nsGkAtoms::feDropShadow, // feDropShadow
306 : &nsGkAtoms::feFlood, // feFlood
307 : &nsGkAtoms::feFuncA, // feFuncA
308 : &nsGkAtoms::feFuncB, // feFuncB
309 : &nsGkAtoms::feFuncG, // feFuncG
310 : &nsGkAtoms::feFuncR, // feFuncR
311 : &nsGkAtoms::feGaussianBlur, // feGaussianBlur
312 : &nsGkAtoms::feImage, // feImage
313 : &nsGkAtoms::feMerge, // feMerge
314 : &nsGkAtoms::feMergeNode, // feMergeNode
315 : &nsGkAtoms::feMorphology, // feMorphology
316 : &nsGkAtoms::feOffset, // feOffset
317 : &nsGkAtoms::fePointLight, // fePointLight
318 : &nsGkAtoms::feSpecularLighting, // feSpecularLighting
319 : &nsGkAtoms::feSpotLight, // feSpotLight
320 : &nsGkAtoms::feTile, // feTile
321 : &nsGkAtoms::feTurbulence, // feTurbulence
322 : &nsGkAtoms::filter, // filter
323 : &nsGkAtoms::font, // font
324 : &nsGkAtoms::font_face, // font-face
325 : &nsGkAtoms::font_face_format, // font-face-format
326 : &nsGkAtoms::font_face_name, // font-face-name
327 : &nsGkAtoms::font_face_src, // font-face-src
328 : &nsGkAtoms::font_face_uri, // font-face-uri
329 : &nsGkAtoms::foreignObject, // foreignObject
330 : &nsGkAtoms::g, // g
331 : // glyph
332 : &nsGkAtoms::glyphRef, // glyphRef
333 : // hkern
334 : &nsGkAtoms::image, // image
335 : &nsGkAtoms::line, // line
336 : &nsGkAtoms::linearGradient, // linearGradient
337 : &nsGkAtoms::marker, // marker
338 : &nsGkAtoms::mask, // mask
339 : &nsGkAtoms::metadata, // metadata
340 : &nsGkAtoms::missingGlyph, // missingGlyph
341 : &nsGkAtoms::mpath, // mpath
342 : &nsGkAtoms::path, // path
343 : &nsGkAtoms::pattern, // pattern
344 : &nsGkAtoms::polygon, // polygon
345 : &nsGkAtoms::polyline, // polyline
346 : &nsGkAtoms::radialGradient, // radialGradient
347 : &nsGkAtoms::rect, // rect
348 : &nsGkAtoms::stop, // stop
349 : &nsGkAtoms::svg, // svg
350 : &nsGkAtoms::svgSwitch, // switch
351 : &nsGkAtoms::symbol, // symbol
352 : &nsGkAtoms::text, // text
353 : &nsGkAtoms::textPath, // textPath
354 : &nsGkAtoms::title, // title
355 : &nsGkAtoms::tref, // tref
356 : &nsGkAtoms::tspan, // tspan
357 : &nsGkAtoms::use, // use
358 : &nsGkAtoms::view, // view
359 : // vkern
360 : nullptr
361 : };
362 :
363 : nsIAtom** const kAttributesSVG[] = {
364 : // accent-height
365 : &nsGkAtoms::accumulate, // accumulate
366 : &nsGkAtoms::additive, // additive
367 : &nsGkAtoms::alignment_baseline, // alignment-baseline
368 : // alphabetic
369 : &nsGkAtoms::amplitude, // amplitude
370 : // arabic-form
371 : // ascent
372 : &nsGkAtoms::attributeName, // attributeName
373 : &nsGkAtoms::attributeType, // attributeType
374 : &nsGkAtoms::azimuth, // azimuth
375 : &nsGkAtoms::baseFrequency, // baseFrequency
376 : &nsGkAtoms::baseline_shift, // baseline-shift
377 : // baseProfile
378 : // bbox
379 : &nsGkAtoms::begin, // begin
380 : &nsGkAtoms::bias, // bias
381 : &nsGkAtoms::by, // by
382 : &nsGkAtoms::calcMode, // calcMode
383 : // cap-height
384 : &nsGkAtoms::_class, // class
385 : &nsGkAtoms::clip_path, // clip-path
386 : &nsGkAtoms::clip_rule, // clip-rule
387 : &nsGkAtoms::clipPathUnits, // clipPathUnits
388 : &nsGkAtoms::color, // color
389 : &nsGkAtoms::colorInterpolation, // color-interpolation
390 : &nsGkAtoms::colorInterpolationFilters, // color-interpolation-filters
391 : &nsGkAtoms::cursor, // cursor
392 : &nsGkAtoms::cx, // cx
393 : &nsGkAtoms::cy, // cy
394 : &nsGkAtoms::d, // d
395 : // descent
396 : &nsGkAtoms::diffuseConstant, // diffuseConstant
397 : &nsGkAtoms::direction, // direction
398 : &nsGkAtoms::display, // display
399 : &nsGkAtoms::divisor, // divisor
400 : &nsGkAtoms::dominant_baseline, // dominant-baseline
401 : &nsGkAtoms::dur, // dur
402 : &nsGkAtoms::dx, // dx
403 : &nsGkAtoms::dy, // dy
404 : &nsGkAtoms::edgeMode, // edgeMode
405 : &nsGkAtoms::elevation, // elevation
406 : // enable-background
407 : &nsGkAtoms::end, // end
408 : &nsGkAtoms::fill, // fill
409 : &nsGkAtoms::fill_opacity, // fill-opacity
410 : &nsGkAtoms::fill_rule, // fill-rule
411 : &nsGkAtoms::filter, // filter
412 : &nsGkAtoms::filterUnits, // filterUnits
413 : &nsGkAtoms::flood_color, // flood-color
414 : &nsGkAtoms::flood_opacity, // flood-opacity
415 : // XXX focusable
416 : &nsGkAtoms::font, // font
417 : &nsGkAtoms::font_family, // font-family
418 : &nsGkAtoms::font_size, // font-size
419 : &nsGkAtoms::font_size_adjust, // font-size-adjust
420 : &nsGkAtoms::font_stretch, // font-stretch
421 : &nsGkAtoms::font_style, // font-style
422 : &nsGkAtoms::font_variant, // font-variant
423 : &nsGkAtoms::fontWeight, // font-weight
424 : &nsGkAtoms::format, // format
425 : &nsGkAtoms::from, // from
426 : &nsGkAtoms::fx, // fx
427 : &nsGkAtoms::fy, // fy
428 : // g1
429 : // g2
430 : // glyph-name
431 : // glyphRef
432 : // glyph-orientation-horizontal
433 : // glyph-orientation-vertical
434 : &nsGkAtoms::gradientTransform, // gradientTransform
435 : &nsGkAtoms::gradientUnits, // gradientUnits
436 : &nsGkAtoms::height, // height
437 : // horiz-adv-x
438 : // horiz-origin-x
439 : // horiz-origin-y
440 : &nsGkAtoms::id, // id
441 : // ideographic
442 : &nsGkAtoms::image_rendering, // image-rendering
443 : &nsGkAtoms::in, // in
444 : &nsGkAtoms::in2, // in2
445 : &nsGkAtoms::intercept, // intercept
446 : // k
447 : &nsGkAtoms::k1, // k1
448 : &nsGkAtoms::k2, // k2
449 : &nsGkAtoms::k3, // k3
450 : &nsGkAtoms::k4, // k4
451 : // kerning
452 : &nsGkAtoms::kernelMatrix, // kernelMatrix
453 : &nsGkAtoms::kernelUnitLength, // kernelUnitLength
454 : &nsGkAtoms::keyPoints, // keyPoints
455 : &nsGkAtoms::keySplines, // keySplines
456 : &nsGkAtoms::keyTimes, // keyTimes
457 : &nsGkAtoms::lang, // lang
458 : // lengthAdjust
459 : &nsGkAtoms::letter_spacing, // letter-spacing
460 : &nsGkAtoms::lighting_color, // lighting-color
461 : &nsGkAtoms::limitingConeAngle, // limitingConeAngle
462 : // local
463 : &nsGkAtoms::marker, // marker
464 : &nsGkAtoms::marker_end, // marker-end
465 : &nsGkAtoms::marker_mid, // marker-mid
466 : &nsGkAtoms::marker_start, // marker-start
467 : &nsGkAtoms::markerHeight, // markerHeight
468 : &nsGkAtoms::markerUnits, // markerUnits
469 : &nsGkAtoms::markerWidth, // markerWidth
470 : &nsGkAtoms::mask, // mask
471 : &nsGkAtoms::maskContentUnits, // maskContentUnits
472 : &nsGkAtoms::maskUnits, // maskUnits
473 : // mathematical
474 : &nsGkAtoms::max, // max
475 : &nsGkAtoms::media, // media
476 : &nsGkAtoms::method, // method
477 : &nsGkAtoms::min, // min
478 : &nsGkAtoms::mode, // mode
479 : &nsGkAtoms::name, // name
480 : &nsGkAtoms::numOctaves, // numOctaves
481 : &nsGkAtoms::offset, // offset
482 : &nsGkAtoms::opacity, // opacity
483 : &nsGkAtoms::_operator, // operator
484 : &nsGkAtoms::order, // order
485 : &nsGkAtoms::orient, // orient
486 : &nsGkAtoms::orientation, // orientation
487 : // origin
488 : // overline-position
489 : // overline-thickness
490 : &nsGkAtoms::overflow, // overflow
491 : // panose-1
492 : &nsGkAtoms::path, // path
493 : &nsGkAtoms::pathLength, // pathLength
494 : &nsGkAtoms::patternContentUnits, // patternContentUnits
495 : &nsGkAtoms::patternTransform, // patternTransform
496 : &nsGkAtoms::patternUnits, // patternUnits
497 : &nsGkAtoms::pointer_events, // pointer-events XXX is this safe?
498 : &nsGkAtoms::points, // points
499 : &nsGkAtoms::pointsAtX, // pointsAtX
500 : &nsGkAtoms::pointsAtY, // pointsAtY
501 : &nsGkAtoms::pointsAtZ, // pointsAtZ
502 : &nsGkAtoms::preserveAlpha, // preserveAlpha
503 : &nsGkAtoms::preserveAspectRatio, // preserveAspectRatio
504 : &nsGkAtoms::primitiveUnits, // primitiveUnits
505 : &nsGkAtoms::r, // r
506 : &nsGkAtoms::radius, // radius
507 : &nsGkAtoms::refX, // refX
508 : &nsGkAtoms::refY, // refY
509 : &nsGkAtoms::repeatCount, // repeatCount
510 : &nsGkAtoms::repeatDur, // repeatDur
511 : &nsGkAtoms::requiredExtensions, // requiredExtensions
512 : &nsGkAtoms::requiredFeatures, // requiredFeatures
513 : &nsGkAtoms::restart, // restart
514 : &nsGkAtoms::result, // result
515 : &nsGkAtoms::rotate, // rotate
516 : &nsGkAtoms::rx, // rx
517 : &nsGkAtoms::ry, // ry
518 : &nsGkAtoms::scale, // scale
519 : &nsGkAtoms::seed, // seed
520 : &nsGkAtoms::shape_rendering, // shape-rendering
521 : &nsGkAtoms::slope, // slope
522 : &nsGkAtoms::spacing, // spacing
523 : &nsGkAtoms::specularConstant, // specularConstant
524 : &nsGkAtoms::specularExponent, // specularExponent
525 : &nsGkAtoms::spreadMethod, // spreadMethod
526 : &nsGkAtoms::startOffset, // startOffset
527 : &nsGkAtoms::stdDeviation, // stdDeviation
528 : // stemh
529 : // stemv
530 : &nsGkAtoms::stitchTiles, // stitchTiles
531 : &nsGkAtoms::stop_color, // stop-color
532 : &nsGkAtoms::stop_opacity, // stop-opacity
533 : // strikethrough-position
534 : // strikethrough-thickness
535 : &nsGkAtoms::string, // string
536 : &nsGkAtoms::stroke, // stroke
537 : &nsGkAtoms::stroke_dasharray, // stroke-dasharray
538 : &nsGkAtoms::stroke_dashoffset, // stroke-dashoffset
539 : &nsGkAtoms::stroke_linecap, // stroke-linecap
540 : &nsGkAtoms::stroke_linejoin, // stroke-linejoin
541 : &nsGkAtoms::stroke_miterlimit, // stroke-miterlimit
542 : &nsGkAtoms::stroke_opacity, // stroke-opacity
543 : &nsGkAtoms::stroke_width, // stroke-width
544 : &nsGkAtoms::surfaceScale, // surfaceScale
545 : &nsGkAtoms::systemLanguage, // systemLanguage
546 : &nsGkAtoms::tableValues, // tableValues
547 : &nsGkAtoms::target, // target
548 : &nsGkAtoms::targetX, // targetX
549 : &nsGkAtoms::targetY, // targetY
550 : &nsGkAtoms::text_anchor, // text-anchor
551 : &nsGkAtoms::text_decoration, // text-decoration
552 : // textLength
553 : &nsGkAtoms::text_rendering, // text-rendering
554 : &nsGkAtoms::title, // title
555 : &nsGkAtoms::to, // to
556 : &nsGkAtoms::transform, // transform
557 : &nsGkAtoms::type, // type
558 : // u1
559 : // u2
560 : // underline-position
561 : // underline-thickness
562 : // unicode
563 : &nsGkAtoms::unicode_bidi, // unicode-bidi
564 : // unicode-range
565 : // units-per-em
566 : // v-alphabetic
567 : // v-hanging
568 : // v-ideographic
569 : // v-mathematical
570 : &nsGkAtoms::values, // values
571 : &nsGkAtoms::vector_effect, // vector-effect
572 : // vert-adv-y
573 : // vert-origin-x
574 : // vert-origin-y
575 : &nsGkAtoms::viewBox, // viewBox
576 : &nsGkAtoms::viewTarget, // viewTarget
577 : &nsGkAtoms::visibility, // visibility
578 : &nsGkAtoms::width, // width
579 : // widths
580 : &nsGkAtoms::word_spacing, // word-spacing
581 : &nsGkAtoms::writing_mode, // writing-mode
582 : &nsGkAtoms::x, // x
583 : // x-height
584 : &nsGkAtoms::x1, // x1
585 : &nsGkAtoms::x2, // x2
586 : &nsGkAtoms::xChannelSelector, // xChannelSelector
587 : &nsGkAtoms::y, // y
588 : &nsGkAtoms::y1, // y1
589 : &nsGkAtoms::y2, // y2
590 : &nsGkAtoms::yChannelSelector, // yChannelSelector
591 : &nsGkAtoms::z, // z
592 : &nsGkAtoms::zoomAndPan, // zoomAndPan
593 : nullptr
594 : };
595 :
596 : nsIAtom** const kURLAttributesSVG[] = {
597 : &nsGkAtoms::href,
598 : nullptr
599 : };
600 :
601 : nsIAtom** const kElementsMathML[] = {
602 : &nsGkAtoms::abs_, // abs
603 : &nsGkAtoms::_and, // and
604 : &nsGkAtoms::annotation_, // annotation
605 : &nsGkAtoms::annotation_xml_, // annotation-xml
606 : &nsGkAtoms::apply_, // apply
607 : &nsGkAtoms::approx_, // approx
608 : &nsGkAtoms::arccos_, // arccos
609 : &nsGkAtoms::arccosh_, // arccosh
610 : &nsGkAtoms::arccot_, // arccot
611 : &nsGkAtoms::arccoth_, // arccoth
612 : &nsGkAtoms::arccsc_, // arccsc
613 : &nsGkAtoms::arccsch_, // arccsch
614 : &nsGkAtoms::arcsec_, // arcsec
615 : &nsGkAtoms::arcsech_, // arcsech
616 : &nsGkAtoms::arcsin_, // arcsin
617 : &nsGkAtoms::arcsinh_, // arcsinh
618 : &nsGkAtoms::arctan_, // arctan
619 : &nsGkAtoms::arctanh_, // arctanh
620 : &nsGkAtoms::arg_, // arg
621 : &nsGkAtoms::bind_, // bind
622 : &nsGkAtoms::bvar_, // bvar
623 : &nsGkAtoms::card_, // card
624 : &nsGkAtoms::cartesianproduct_, // cartesianproduct
625 : &nsGkAtoms::cbytes_, // cbytes
626 : &nsGkAtoms::ceiling, // ceiling
627 : &nsGkAtoms::cerror_, // cerror
628 : &nsGkAtoms::ci_, // ci
629 : &nsGkAtoms::cn_, // cn
630 : &nsGkAtoms::codomain_, // codomain
631 : &nsGkAtoms::complexes_, // complexes
632 : &nsGkAtoms::compose_, // compose
633 : &nsGkAtoms::condition_, // condition
634 : &nsGkAtoms::conjugate_, // conjugate
635 : &nsGkAtoms::cos_, // cos
636 : &nsGkAtoms::cosh_, // cosh
637 : &nsGkAtoms::cot_, // cot
638 : &nsGkAtoms::coth_, // coth
639 : &nsGkAtoms::cs_, // cs
640 : &nsGkAtoms::csc_, // csc
641 : &nsGkAtoms::csch_, // csch
642 : &nsGkAtoms::csymbol_, // csymbol
643 : &nsGkAtoms::curl_, // curl
644 : &nsGkAtoms::declare, // declare
645 : &nsGkAtoms::degree_, // degree
646 : &nsGkAtoms::determinant_, // determinant
647 : &nsGkAtoms::diff_, // diff
648 : &nsGkAtoms::divergence_, // divergence
649 : &nsGkAtoms::divide_, // divide
650 : &nsGkAtoms::domain_, // domain
651 : &nsGkAtoms::domainofapplication_, // domainofapplication
652 : &nsGkAtoms::el_, // el
653 : &nsGkAtoms::emptyset_, // emptyset
654 : &nsGkAtoms::eq_, // eq
655 : &nsGkAtoms::equivalent_, // equivalent
656 : &nsGkAtoms::eulergamma_, // eulergamma
657 : &nsGkAtoms::exists_, // exists
658 : &nsGkAtoms::exp_, // exp
659 : &nsGkAtoms::exponentiale_, // exponentiale
660 : &nsGkAtoms::factorial_, // factorial
661 : &nsGkAtoms::factorof_, // factorof
662 : &nsGkAtoms::_false, // false
663 : &nsGkAtoms::floor, // floor
664 : &nsGkAtoms::fn_, // fn
665 : &nsGkAtoms::forall_, // forall
666 : &nsGkAtoms::gcd_, // gcd
667 : &nsGkAtoms::geq_, // geq
668 : &nsGkAtoms::grad, // grad
669 : &nsGkAtoms::gt_, // gt
670 : &nsGkAtoms::ident_, // ident
671 : &nsGkAtoms::image, // image
672 : &nsGkAtoms::imaginary_, // imaginary
673 : &nsGkAtoms::imaginaryi_, // imaginaryi
674 : &nsGkAtoms::implies_, // implies
675 : &nsGkAtoms::in, // in
676 : &nsGkAtoms::infinity, // infinity
677 : &nsGkAtoms::int_, // int
678 : &nsGkAtoms::integers_, // integers
679 : &nsGkAtoms::intersect_, // intersect
680 : &nsGkAtoms::interval_, // interval
681 : &nsGkAtoms::inverse_, // inverse
682 : &nsGkAtoms::lambda_, // lambda
683 : &nsGkAtoms::laplacian_, // laplacian
684 : &nsGkAtoms::lcm_, // lcm
685 : &nsGkAtoms::leq_, // leq
686 : &nsGkAtoms::limit_, // limit
687 : &nsGkAtoms::list_, // list
688 : &nsGkAtoms::ln_, // ln
689 : &nsGkAtoms::log_, // log
690 : &nsGkAtoms::logbase_, // logbase
691 : &nsGkAtoms::lowlimit_, // lowlimit
692 : &nsGkAtoms::lt_, // lt
693 : &nsGkAtoms::maction_, // maction
694 : &nsGkAtoms::maligngroup_, // maligngroup
695 : &nsGkAtoms::malignmark_, // malignmark
696 : &nsGkAtoms::math, // math
697 : &nsGkAtoms::matrix, // matrix
698 : &nsGkAtoms::matrixrow_, // matrixrow
699 : &nsGkAtoms::max, // max
700 : &nsGkAtoms::mean_, // mean
701 : &nsGkAtoms::median_, // median
702 : &nsGkAtoms::menclose_, // menclose
703 : &nsGkAtoms::merror_, // merror
704 : &nsGkAtoms::mfenced_, // mfenced
705 : &nsGkAtoms::mfrac_, // mfrac
706 : &nsGkAtoms::mglyph_, // mglyph
707 : &nsGkAtoms::mi_, // mi
708 : &nsGkAtoms::min, // min
709 : &nsGkAtoms::minus_, // minus
710 : &nsGkAtoms::mlabeledtr_, // mlabeledtr
711 : &nsGkAtoms::mlongdiv_, // mlongdiv
712 : &nsGkAtoms::mmultiscripts_, // mmultiscripts
713 : &nsGkAtoms::mn_, // mn
714 : &nsGkAtoms::mo_, // mo
715 : &nsGkAtoms::mode, // mode
716 : &nsGkAtoms::moment_, // moment
717 : &nsGkAtoms::momentabout_, // momentabout
718 : &nsGkAtoms::mover_, // mover
719 : &nsGkAtoms::mpadded_, // mpadded
720 : &nsGkAtoms::mphantom_, // mphantom
721 : &nsGkAtoms::mprescripts_, // mprescripts
722 : &nsGkAtoms::mroot_, // mroot
723 : &nsGkAtoms::mrow_, // mrow
724 : &nsGkAtoms::ms_, // ms
725 : &nsGkAtoms::mscarries_, // mscarries
726 : &nsGkAtoms::mscarry_, // mscarry
727 : &nsGkAtoms::msgroup_, // msgroup
728 : &nsGkAtoms::msline_, // msline
729 : &nsGkAtoms::mspace_, // mspace
730 : &nsGkAtoms::msqrt_, // msqrt
731 : &nsGkAtoms::msrow_, // msrow
732 : &nsGkAtoms::mstack_, // mstack
733 : &nsGkAtoms::mstyle_, // mstyle
734 : &nsGkAtoms::msub_, // msub
735 : &nsGkAtoms::msubsup_, // msubsup
736 : &nsGkAtoms::msup_, // msup
737 : &nsGkAtoms::mtable_, // mtable
738 : &nsGkAtoms::mtd_, // mtd
739 : &nsGkAtoms::mtext_, // mtext
740 : &nsGkAtoms::mtr_, // mtr
741 : &nsGkAtoms::munder_, // munder
742 : &nsGkAtoms::munderover_, // munderover
743 : &nsGkAtoms::naturalnumbers_, // naturalnumbers
744 : &nsGkAtoms::neq_, // neq
745 : &nsGkAtoms::none, // none
746 : &nsGkAtoms::_not, // not
747 : &nsGkAtoms::notanumber_, // notanumber
748 : &nsGkAtoms::note_, // note
749 : &nsGkAtoms::notin_, // notin
750 : &nsGkAtoms::notprsubset_, // notprsubset
751 : &nsGkAtoms::notsubset_, // notsubset
752 : &nsGkAtoms::_or, // or
753 : &nsGkAtoms::otherwise, // otherwise
754 : &nsGkAtoms::outerproduct_, // outerproduct
755 : &nsGkAtoms::partialdiff_, // partialdiff
756 : &nsGkAtoms::pi_, // pi
757 : &nsGkAtoms::piece_, // piece
758 : &nsGkAtoms::piecewise_, // piecewise
759 : &nsGkAtoms::plus_, // plus
760 : &nsGkAtoms::power_, // power
761 : &nsGkAtoms::primes_, // primes
762 : &nsGkAtoms::product_, // product
763 : &nsGkAtoms::prsubset_, // prsubset
764 : &nsGkAtoms::quotient_, // quotient
765 : &nsGkAtoms::rationals_, // rationals
766 : &nsGkAtoms::real_, // real
767 : &nsGkAtoms::reals_, // reals
768 : &nsGkAtoms::reln_, // reln
769 : &nsGkAtoms::rem, // rem
770 : &nsGkAtoms::root_, // root
771 : &nsGkAtoms::scalarproduct_, // scalarproduct
772 : &nsGkAtoms::sdev_, // sdev
773 : &nsGkAtoms::sec_, // sec
774 : &nsGkAtoms::sech_, // sech
775 : &nsGkAtoms::selector_, // selector
776 : &nsGkAtoms::semantics_, // semantics
777 : &nsGkAtoms::sep_, // sep
778 : &nsGkAtoms::set_, // set
779 : &nsGkAtoms::setdiff_, // setdiff
780 : &nsGkAtoms::share_, // share
781 : &nsGkAtoms::sin_, // sin
782 : &nsGkAtoms::sinh_, // sinh
783 : &nsGkAtoms::subset_, // subset
784 : &nsGkAtoms::sum, // sum
785 : &nsGkAtoms::tan_, // tan
786 : &nsGkAtoms::tanh_, // tanh
787 : &nsGkAtoms::tendsto_, // tendsto
788 : &nsGkAtoms::times_, // times
789 : &nsGkAtoms::transpose_, // transpose
790 : &nsGkAtoms::_true, // true
791 : &nsGkAtoms::union_, // union
792 : &nsGkAtoms::uplimit_, // uplimit
793 : &nsGkAtoms::variance_, // variance
794 : &nsGkAtoms::vector_, // vector
795 : &nsGkAtoms::vectorproduct_, // vectorproduct
796 : &nsGkAtoms::xor_, // xor
797 : nullptr
798 : };
799 :
800 : nsIAtom** const kAttributesMathML[] = {
801 : &nsGkAtoms::accent_, // accent
802 : &nsGkAtoms::accentunder_, // accentunder
803 : &nsGkAtoms::actiontype_, // actiontype
804 : &nsGkAtoms::align, // align
805 : &nsGkAtoms::alignmentscope_, // alignmentscope
806 : &nsGkAtoms::alt, // alt
807 : &nsGkAtoms::altimg_, // altimg
808 : &nsGkAtoms::altimg_height_, // altimg-height
809 : &nsGkAtoms::altimg_valign_, // altimg-valign
810 : &nsGkAtoms::altimg_width_, // altimg-width
811 : &nsGkAtoms::background, // background
812 : &nsGkAtoms::base, // base
813 : &nsGkAtoms::bevelled_, // bevelled
814 : &nsGkAtoms::cd_, // cd
815 : &nsGkAtoms::cdgroup_, // cdgroup
816 : &nsGkAtoms::charalign_, // charalign
817 : &nsGkAtoms::close, // close
818 : &nsGkAtoms::closure_, // closure
819 : &nsGkAtoms::color, // color
820 : &nsGkAtoms::columnalign_, // columnalign
821 : &nsGkAtoms::columnalignment_, // columnalignment
822 : &nsGkAtoms::columnlines_, // columnlines
823 : &nsGkAtoms::columnspacing_, // columnspacing
824 : &nsGkAtoms::columnspan_, // columnspan
825 : &nsGkAtoms::columnwidth_, // columnwidth
826 : &nsGkAtoms::crossout_, // crossout
827 : &nsGkAtoms::decimalpoint_, // decimalpoint
828 : &nsGkAtoms::definitionURL_, // definitionURL
829 : &nsGkAtoms::denomalign_, // denomalign
830 : &nsGkAtoms::depth_, // depth
831 : &nsGkAtoms::dir, // dir
832 : &nsGkAtoms::display, // display
833 : &nsGkAtoms::displaystyle_, // displaystyle
834 : &nsGkAtoms::edge_, // edge
835 : &nsGkAtoms::encoding, // encoding
836 : &nsGkAtoms::equalcolumns_, // equalcolumns
837 : &nsGkAtoms::equalrows_, // equalrows
838 : &nsGkAtoms::fence_, // fence
839 : &nsGkAtoms::fontfamily_, // fontfamily
840 : &nsGkAtoms::fontsize_, // fontsize
841 : &nsGkAtoms::fontstyle_, // fontstyle
842 : &nsGkAtoms::fontweight_, // fontweight
843 : &nsGkAtoms::form, // form
844 : &nsGkAtoms::frame, // frame
845 : &nsGkAtoms::framespacing_, // framespacing
846 : &nsGkAtoms::groupalign_, // groupalign
847 : &nsGkAtoms::height, // height
848 : &nsGkAtoms::href, // href
849 : &nsGkAtoms::id, // id
850 : &nsGkAtoms::indentalign_, // indentalign
851 : &nsGkAtoms::indentalignfirst_, // indentalignfirst
852 : &nsGkAtoms::indentalignlast_, // indentalignlast
853 : &nsGkAtoms::indentshift_, // indentshift
854 : &nsGkAtoms::indentshiftfirst_, // indentshiftfirst
855 : &nsGkAtoms::indenttarget_, // indenttarget
856 : &nsGkAtoms::index, // index
857 : &nsGkAtoms::integer, // integer
858 : &nsGkAtoms::largeop_, // largeop
859 : &nsGkAtoms::length, // length
860 : &nsGkAtoms::linebreak_, // linebreak
861 : &nsGkAtoms::linebreakmultchar_, // linebreakmultchar
862 : &nsGkAtoms::linebreakstyle_, // linebreakstyle
863 : &nsGkAtoms::linethickness_, // linethickness
864 : &nsGkAtoms::location_, // location
865 : &nsGkAtoms::longdivstyle_, // longdivstyle
866 : &nsGkAtoms::lquote_, // lquote
867 : &nsGkAtoms::lspace_, // lspace
868 : &nsGkAtoms::ltr, // ltr
869 : &nsGkAtoms::mathbackground_, // mathbackground
870 : &nsGkAtoms::mathcolor_, // mathcolor
871 : &nsGkAtoms::mathsize_, // mathsize
872 : &nsGkAtoms::mathvariant_, // mathvariant
873 : &nsGkAtoms::maxsize_, // maxsize
874 : &nsGkAtoms::minlabelspacing_, // minlabelspacing
875 : &nsGkAtoms::minsize_, // minsize
876 : &nsGkAtoms::movablelimits_, // movablelimits
877 : &nsGkAtoms::msgroup_, // msgroup
878 : &nsGkAtoms::name, // name
879 : &nsGkAtoms::newline, // newline
880 : &nsGkAtoms::notation_, // notation
881 : &nsGkAtoms::numalign_, // numalign
882 : &nsGkAtoms::number, // number
883 : &nsGkAtoms::open, // open
884 : &nsGkAtoms::order, // order
885 : &nsGkAtoms::other_, // other
886 : &nsGkAtoms::overflow, // overflow
887 : &nsGkAtoms::position, // position
888 : &nsGkAtoms::role, // role
889 : &nsGkAtoms::rowalign_, // rowalign
890 : &nsGkAtoms::rowlines_, // rowlines
891 : &nsGkAtoms::rowspacing_, // rowspacing
892 : &nsGkAtoms::rowspan, // rowspan
893 : &nsGkAtoms::rquote_, // rquote
894 : &nsGkAtoms::rspace_, // rspace
895 : &nsGkAtoms::schemaLocation_, // schemaLocation
896 : &nsGkAtoms::scriptlevel_, // scriptlevel
897 : &nsGkAtoms::scriptminsize_, // scriptminsize
898 : &nsGkAtoms::scriptsize_, // scriptsize
899 : &nsGkAtoms::scriptsizemultiplier_, // scriptsizemultiplier
900 : &nsGkAtoms::selection_, // selection
901 : &nsGkAtoms::separator_, // separator
902 : &nsGkAtoms::separators_, // separators
903 : &nsGkAtoms::shift_, // shift
904 : &nsGkAtoms::side_, // side
905 : &nsGkAtoms::src, // src
906 : &nsGkAtoms::stackalign_, // stackalign
907 : &nsGkAtoms::stretchy_, // stretchy
908 : &nsGkAtoms::subscriptshift_, // subscriptshift
909 : &nsGkAtoms::superscriptshift_, // superscriptshift
910 : &nsGkAtoms::symmetric_, // symmetric
911 : &nsGkAtoms::type, // type
912 : &nsGkAtoms::voffset_, // voffset
913 : &nsGkAtoms::width, // width
914 : &nsGkAtoms::xref_, // xref
915 : nullptr
916 : };
917 :
918 : nsIAtom** const kURLAttributesMathML[] = {
919 : &nsGkAtoms::href,
920 : &nsGkAtoms::src,
921 : &nsGkAtoms::cdgroup_,
922 : &nsGkAtoms::altimg_,
923 : &nsGkAtoms::definitionURL_,
924 : nullptr
925 : };
926 :
927 : nsTHashtable<nsISupportsHashKey>* nsTreeSanitizer::sElementsHTML = nullptr;
928 : nsTHashtable<nsISupportsHashKey>* nsTreeSanitizer::sAttributesHTML = nullptr;
929 : nsTHashtable<nsISupportsHashKey>* nsTreeSanitizer::sPresAttributesHTML = nullptr;
930 : nsTHashtable<nsISupportsHashKey>* nsTreeSanitizer::sElementsSVG = nullptr;
931 : nsTHashtable<nsISupportsHashKey>* nsTreeSanitizer::sAttributesSVG = nullptr;
932 : nsTHashtable<nsISupportsHashKey>* nsTreeSanitizer::sElementsMathML = nullptr;
933 : nsTHashtable<nsISupportsHashKey>* nsTreeSanitizer::sAttributesMathML = nullptr;
934 : nsIPrincipal* nsTreeSanitizer::sNullPrincipal = nullptr;
935 :
936 0 : nsTreeSanitizer::nsTreeSanitizer(uint32_t aFlags)
937 0 : : mAllowStyles(aFlags & nsIParserUtils::SanitizerAllowStyle)
938 0 : , mAllowComments(aFlags & nsIParserUtils::SanitizerAllowComments)
939 0 : , mDropNonCSSPresentation(aFlags &
940 : nsIParserUtils::SanitizerDropNonCSSPresentation)
941 0 : , mDropForms(aFlags & nsIParserUtils::SanitizerDropForms)
942 0 : , mCidEmbedsOnly(aFlags &
943 : nsIParserUtils::SanitizerCidEmbedsOnly)
944 0 : , mDropMedia(aFlags & nsIParserUtils::SanitizerDropMedia)
945 0 : , mFullDocument(false)
946 : {
947 0 : if (mCidEmbedsOnly) {
948 : // Sanitizing styles for external references is not supported.
949 0 : mAllowStyles = false;
950 : }
951 0 : if (!sElementsHTML) {
952 : // Initialize lazily to avoid having to initialize at all if the user
953 : // doesn't paste HTML or load feeds.
954 0 : InitializeStatics();
955 : }
956 0 : }
957 :
958 : bool
959 0 : nsTreeSanitizer::MustFlatten(int32_t aNamespace, nsIAtom* aLocal)
960 : {
961 0 : if (aNamespace == kNameSpaceID_XHTML) {
962 0 : if (mDropNonCSSPresentation && (nsGkAtoms::font == aLocal ||
963 0 : nsGkAtoms::center == aLocal)) {
964 0 : return true;
965 : }
966 0 : if (mDropForms && (nsGkAtoms::form == aLocal ||
967 0 : nsGkAtoms::input == aLocal ||
968 0 : nsGkAtoms::keygen == aLocal ||
969 0 : nsGkAtoms::option == aLocal ||
970 0 : nsGkAtoms::optgroup == aLocal)) {
971 0 : return true;
972 : }
973 0 : if (mFullDocument && (nsGkAtoms::title == aLocal ||
974 0 : nsGkAtoms::html == aLocal ||
975 0 : nsGkAtoms::head == aLocal ||
976 0 : nsGkAtoms::body == aLocal)) {
977 0 : return false;
978 : }
979 0 : return !sElementsHTML->GetEntry(aLocal);
980 : }
981 0 : if (aNamespace == kNameSpaceID_SVG) {
982 0 : if (mCidEmbedsOnly || mDropMedia) {
983 : // Sanitizing CSS-based URL references inside SVG presentational
984 : // attributes is not supported, so flattening for cid: embed case.
985 0 : return true;
986 : }
987 0 : return !sElementsSVG->GetEntry(aLocal);
988 : }
989 0 : if (aNamespace == kNameSpaceID_MathML) {
990 0 : return !sElementsMathML->GetEntry(aLocal);
991 : }
992 0 : return true;
993 : }
994 :
995 : bool
996 0 : nsTreeSanitizer::IsURL(nsIAtom*** aURLs, nsIAtom* aLocalName)
997 : {
998 : nsIAtom** atomPtrPtr;
999 0 : while ((atomPtrPtr = *aURLs)) {
1000 0 : if (*atomPtrPtr == aLocalName) {
1001 0 : return true;
1002 : }
1003 0 : ++aURLs;
1004 : }
1005 0 : return false;
1006 : }
1007 :
1008 : bool
1009 0 : nsTreeSanitizer::MustPrune(int32_t aNamespace,
1010 : nsIAtom* aLocal,
1011 : mozilla::dom::Element* aElement)
1012 : {
1013 : // To avoid attacks where a MathML script becomes something that gets
1014 : // serialized in a way that it parses back as an HTML script, let's just
1015 : // drop elements with the local name 'script' regardless of namespace.
1016 0 : if (nsGkAtoms::script == aLocal) {
1017 0 : return true;
1018 : }
1019 0 : if (aNamespace == kNameSpaceID_XHTML) {
1020 0 : if (nsGkAtoms::title == aLocal && !mFullDocument) {
1021 : // emulate the quirks of the old parser
1022 0 : return true;
1023 : }
1024 0 : if (mDropForms && (nsGkAtoms::select == aLocal ||
1025 0 : nsGkAtoms::button == aLocal ||
1026 0 : nsGkAtoms::datalist == aLocal)) {
1027 0 : return true;
1028 : }
1029 0 : if (mDropMedia && (nsGkAtoms::img == aLocal ||
1030 0 : nsGkAtoms::video == aLocal ||
1031 0 : nsGkAtoms::audio == aLocal ||
1032 0 : nsGkAtoms::source == aLocal)) {
1033 0 : return true;
1034 : }
1035 0 : if (nsGkAtoms::meta == aLocal &&
1036 0 : (aElement->HasAttr(kNameSpaceID_None, nsGkAtoms::charset) ||
1037 0 : aElement->HasAttr(kNameSpaceID_None, nsGkAtoms::httpEquiv))) {
1038 : // Throw away charset declarations even if they also have microdata
1039 : // which they can't validly have.
1040 0 : return true;
1041 : }
1042 0 : if (((!mFullDocument && nsGkAtoms::meta == aLocal) ||
1043 0 : nsGkAtoms::link == aLocal) &&
1044 0 : !(aElement->HasAttr(kNameSpaceID_None, nsGkAtoms::itemprop) ||
1045 0 : aElement->HasAttr(kNameSpaceID_None, nsGkAtoms::itemscope))) {
1046 : // emulate old behavior for non-Microdata <meta> and <link> presumably
1047 : // in <head>. <meta> and <link> are whitelisted in order to avoid
1048 : // corrupting Microdata when they appear in <body>. Note that
1049 : // SanitizeAttributes() will remove the rel attribute from <link> and
1050 : // the name attribute from <meta>.
1051 0 : return true;
1052 : }
1053 : }
1054 0 : if (mAllowStyles) {
1055 0 : if (nsGkAtoms::style == aLocal && !(aNamespace == kNameSpaceID_XHTML
1056 : || aNamespace == kNameSpaceID_SVG)) {
1057 0 : return true;
1058 : }
1059 0 : return false;
1060 : }
1061 0 : if (nsGkAtoms::style == aLocal) {
1062 0 : return true;
1063 : }
1064 0 : return false;
1065 : }
1066 :
1067 : bool
1068 0 : nsTreeSanitizer::SanitizeStyleDeclaration(mozilla::css::Declaration* aDeclaration,
1069 : nsAutoString& aRuleText)
1070 : {
1071 0 : bool didSanitize = aDeclaration->HasProperty(eCSSProperty__moz_binding);
1072 0 : aDeclaration->RemovePropertyByID(eCSSProperty__moz_binding);
1073 0 : aDeclaration->ToString(aRuleText);
1074 0 : return didSanitize;
1075 : }
1076 :
1077 : bool
1078 0 : nsTreeSanitizer::SanitizeStyleSheet(const nsAString& aOriginal,
1079 : nsAString& aSanitized,
1080 : nsIDocument* aDocument,
1081 : nsIURI* aBaseURI)
1082 : {
1083 : nsresult rv;
1084 0 : aSanitized.Truncate();
1085 : // aSanitized will hold the permitted CSS text.
1086 : // -moz-binding is blacklisted.
1087 0 : bool didSanitize = false;
1088 : // Create a sheet to hold the parsed CSS
1089 : RefPtr<CSSStyleSheet> sheet =
1090 : new CSSStyleSheet(mozilla::css::eAuthorSheetFeatures,
1091 0 : CORS_NONE, aDocument->GetReferrerPolicy());
1092 0 : sheet->SetURIs(aDocument->GetDocumentURI(), nullptr, aBaseURI);
1093 0 : sheet->SetPrincipal(aDocument->NodePrincipal());
1094 : // Create the CSS parser, and parse the CSS text.
1095 0 : nsCSSParser parser(nullptr, sheet);
1096 0 : rv = parser.ParseSheet(aOriginal, aDocument->GetDocumentURI(), aBaseURI,
1097 0 : aDocument->NodePrincipal(), 0);
1098 0 : NS_ENSURE_SUCCESS(rv, true);
1099 : // Mark the sheet as complete.
1100 0 : MOZ_ASSERT(!sheet->IsModified(),
1101 : "should not get marked modified during parsing");
1102 0 : sheet->SetComplete();
1103 : // Loop through all the rules found in the CSS text
1104 0 : int32_t ruleCount = sheet->StyleRuleCount();
1105 0 : for (int32_t i = 0; i < ruleCount; ++i) {
1106 0 : mozilla::css::Rule* rule = sheet->GetStyleRuleAt(i);
1107 0 : if (!rule)
1108 0 : continue;
1109 0 : switch (rule->GetType()) {
1110 : default:
1111 0 : didSanitize = true;
1112 : // Ignore these rule types.
1113 0 : break;
1114 : case mozilla::css::Rule::NAMESPACE_RULE:
1115 : case mozilla::css::Rule::FONT_FACE_RULE: {
1116 : // Append @namespace and @font-face rules verbatim.
1117 0 : nsAutoString cssText;
1118 0 : nsCOMPtr<nsIDOMCSSRule> styleRule = do_QueryInterface(rule);
1119 0 : if (styleRule) {
1120 0 : rv = styleRule->GetCssText(cssText);
1121 0 : if (NS_SUCCEEDED(rv)) {
1122 0 : aSanitized.Append(cssText);
1123 : }
1124 : }
1125 0 : break;
1126 : }
1127 : case mozilla::css::Rule::STYLE_RULE: {
1128 : // For style rules, we will just look for and remove the
1129 : // -moz-binding properties.
1130 0 : RefPtr<mozilla::css::StyleRule> styleRule = do_QueryObject(rule);
1131 0 : NS_ASSERTION(styleRule, "Must be a style rule");
1132 0 : nsAutoString decl;
1133 : bool sanitized =
1134 0 : SanitizeStyleDeclaration(styleRule->GetDeclaration(), decl);
1135 0 : didSanitize = sanitized || didSanitize;
1136 0 : if (!sanitized) {
1137 0 : styleRule->GetCssText(decl);
1138 : }
1139 0 : aSanitized.Append(decl);
1140 : }
1141 : }
1142 : }
1143 0 : return didSanitize;
1144 : }
1145 :
1146 : void
1147 0 : nsTreeSanitizer::SanitizeAttributes(mozilla::dom::Element* aElement,
1148 : nsTHashtable<nsISupportsHashKey>* aAllowed,
1149 : nsIAtom*** aURLs,
1150 : bool aAllowXLink,
1151 : bool aAllowStyle,
1152 : bool aAllowDangerousSrc)
1153 : {
1154 0 : uint32_t ac = aElement->GetAttrCount();
1155 :
1156 0 : for (int32_t i = ac - 1; i >= 0; --i) {
1157 0 : const nsAttrName* attrName = aElement->GetAttrNameAt(i);
1158 0 : int32_t attrNs = attrName->NamespaceID();
1159 0 : nsCOMPtr<nsIAtom> attrLocal = attrName->LocalName();
1160 :
1161 0 : if (kNameSpaceID_None == attrNs) {
1162 0 : if (aAllowStyle && nsGkAtoms::style == attrLocal) {
1163 0 : nsCOMPtr<nsIURI> baseURI = aElement->GetBaseURI();
1164 0 : nsIDocument* document = aElement->OwnerDoc();
1165 : // Pass the CSS Loader object to the parser, to allow parser error
1166 : // reports to include the outer window ID.
1167 0 : nsCSSParser parser(document->CSSLoader());
1168 0 : nsAutoString value;
1169 0 : aElement->GetAttr(attrNs, attrLocal, value);
1170 : RefPtr<mozilla::css::Declaration> decl =
1171 0 : parser.ParseStyleAttribute(value, document->GetDocumentURI(),
1172 0 : baseURI, document->NodePrincipal());
1173 0 : if (decl) {
1174 0 : nsAutoString cleanValue;
1175 0 : if (SanitizeStyleDeclaration(decl, cleanValue)) {
1176 : aElement->SetAttr(kNameSpaceID_None,
1177 : nsGkAtoms::style,
1178 : cleanValue,
1179 0 : false);
1180 : }
1181 : }
1182 0 : continue;
1183 : }
1184 0 : if (aAllowDangerousSrc && nsGkAtoms::src == attrLocal) {
1185 0 : continue;
1186 : }
1187 0 : if (IsURL(aURLs, attrLocal)) {
1188 0 : if (SanitizeURL(aElement, attrNs, attrLocal)) {
1189 : // in case the attribute removal shuffled the attribute order, start
1190 : // the loop again.
1191 0 : --ac;
1192 0 : i = ac; // i will be decremented immediately thanks to the for loop
1193 0 : continue;
1194 : }
1195 : // else fall through to see if there's another reason to drop this
1196 : // attribute (in particular if the attribute is background="" on an
1197 : // HTML element)
1198 : }
1199 0 : if (!mDropNonCSSPresentation &&
1200 0 : (aAllowed == sAttributesHTML) && // element is HTML
1201 0 : sPresAttributesHTML->GetEntry(attrLocal)) {
1202 0 : continue;
1203 : }
1204 0 : if (aAllowed->GetEntry(attrLocal) &&
1205 0 : !((attrLocal == nsGkAtoms::rel &&
1206 0 : aElement->IsHTMLElement(nsGkAtoms::link)) ||
1207 0 : (!mFullDocument &&
1208 0 : attrLocal == nsGkAtoms::name &&
1209 0 : aElement->IsHTMLElement(nsGkAtoms::meta)))) {
1210 : // name="" and rel="" are whitelisted, but treat them as blacklisted
1211 : // for <meta name> (fragment case) and <link rel> (all cases) to avoid
1212 : // document-wide metadata or styling overrides with non-conforming
1213 : // <meta name itemprop> or
1214 : // <link rel itemprop>
1215 0 : continue;
1216 : }
1217 0 : const char16_t* localStr = attrLocal->GetUTF16String();
1218 : // Allow underscore to cater to the MCE editor library.
1219 : // Allow data-* on SVG and MathML, too, as a forward-compat measure.
1220 0 : if (*localStr == '_' || (attrLocal->GetLength() > 5 && localStr[0] == 'd'
1221 0 : && localStr[1] == 'a' && localStr[2] == 't' && localStr[3] == 'a'
1222 0 : && localStr[4] == '-')) {
1223 0 : continue;
1224 : }
1225 : // else not allowed
1226 0 : } else if (kNameSpaceID_XML == attrNs) {
1227 0 : if (nsGkAtoms::base == attrLocal) {
1228 0 : if (SanitizeURL(aElement, attrNs, attrLocal)) {
1229 : // in case the attribute removal shuffled the attribute order, start
1230 : // the loop again.
1231 0 : --ac;
1232 0 : i = ac; // i will be decremented immediately thanks to the for loop
1233 : }
1234 0 : continue;
1235 : }
1236 0 : if (nsGkAtoms::lang == attrLocal || nsGkAtoms::space == attrLocal) {
1237 0 : continue;
1238 : }
1239 : // else not allowed
1240 0 : } else if (aAllowXLink && kNameSpaceID_XLink == attrNs) {
1241 0 : if (nsGkAtoms::href == attrLocal) {
1242 0 : if (SanitizeURL(aElement, attrNs, attrLocal)) {
1243 : // in case the attribute removal shuffled the attribute order, start
1244 : // the loop again.
1245 0 : --ac;
1246 0 : i = ac; // i will be decremented immediately thanks to the for loop
1247 : }
1248 0 : continue;
1249 : }
1250 0 : if (nsGkAtoms::type == attrLocal || nsGkAtoms::title == attrLocal
1251 0 : || nsGkAtoms::show == attrLocal || nsGkAtoms::actuate == attrLocal) {
1252 0 : continue;
1253 : }
1254 : // else not allowed
1255 : }
1256 0 : aElement->UnsetAttr(kNameSpaceID_None, attrLocal, false);
1257 : // in case the attribute removal shuffled the attribute order, start the
1258 : // loop again.
1259 0 : --ac;
1260 0 : i = ac; // i will be decremented immediately thanks to the for loop
1261 : }
1262 :
1263 : // If we've got HTML audio or video, add the controls attribute, because
1264 : // otherwise the content is unplayable with scripts removed.
1265 0 : if (aElement->IsAnyOfHTMLElements(nsGkAtoms::video, nsGkAtoms::audio)) {
1266 0 : aElement->SetAttr(kNameSpaceID_None,
1267 : nsGkAtoms::controls,
1268 0 : EmptyString(),
1269 0 : false);
1270 : }
1271 0 : }
1272 :
1273 : bool
1274 0 : nsTreeSanitizer::SanitizeURL(mozilla::dom::Element* aElement,
1275 : int32_t aNamespace,
1276 : nsIAtom* aLocalName)
1277 : {
1278 0 : nsAutoString value;
1279 0 : aElement->GetAttr(aNamespace, aLocalName, value);
1280 :
1281 : // Get value and remove mandatory quotes
1282 : static const char* kWhitespace = "\n\r\t\b";
1283 : const nsAString& v =
1284 0 : nsContentUtils::TrimCharsInSet(kWhitespace, value);
1285 : // Fragment-only url cannot be harmful.
1286 0 : if (!v.IsEmpty() && v.First() == u'#') {
1287 0 : return false;
1288 : }
1289 :
1290 0 : nsIScriptSecurityManager* secMan = nsContentUtils::GetSecurityManager();
1291 0 : uint32_t flags = nsIScriptSecurityManager::DISALLOW_INHERIT_PRINCIPAL;
1292 :
1293 0 : nsCOMPtr<nsIURI> baseURI = aElement->GetBaseURI();
1294 0 : nsCOMPtr<nsIURI> attrURI;
1295 0 : nsresult rv = NS_NewURI(getter_AddRefs(attrURI), v, nullptr, baseURI);
1296 0 : if (NS_SUCCEEDED(rv)) {
1297 0 : if (mCidEmbedsOnly &&
1298 : kNameSpaceID_None == aNamespace) {
1299 0 : if (nsGkAtoms::src == aLocalName || nsGkAtoms::background == aLocalName) {
1300 : // comm-central uses a hack that makes nsIURIs created with cid: specs
1301 : // actually have an about:blank spec. Therefore, nsIURI facilities are
1302 : // useless for cid: when comm-central code is participating.
1303 0 : if (!(v.Length() > 4 &&
1304 0 : (v[0] == 'c' || v[0] == 'C') &&
1305 0 : (v[1] == 'i' || v[1] == 'I') &&
1306 0 : (v[2] == 'd' || v[2] == 'D') &&
1307 0 : v[3] == ':')) {
1308 0 : rv = NS_ERROR_FAILURE;
1309 : }
1310 0 : } else if (nsGkAtoms::cdgroup_ == aLocalName ||
1311 0 : nsGkAtoms::altimg_ == aLocalName ||
1312 0 : nsGkAtoms::definitionURL_ == aLocalName) {
1313 : // Gecko doesn't fetch these now and shouldn't in the future, but
1314 : // in case someone goofs with these in the future, let's drop them.
1315 0 : rv = NS_ERROR_FAILURE;
1316 : } else {
1317 0 : rv = secMan->CheckLoadURIWithPrincipal(sNullPrincipal, attrURI, flags);
1318 : }
1319 : } else {
1320 0 : rv = secMan->CheckLoadURIWithPrincipal(sNullPrincipal, attrURI, flags);
1321 : }
1322 : }
1323 0 : if (NS_FAILED(rv)) {
1324 0 : aElement->UnsetAttr(aNamespace, aLocalName, false);
1325 0 : return true;
1326 : }
1327 0 : return false;
1328 : }
1329 :
1330 : void
1331 0 : nsTreeSanitizer::Sanitize(nsIContent* aFragment)
1332 : {
1333 : // If you want to relax these preconditions, be sure to check the code in
1334 : // here that notifies / does not notify or that fires mutation events if
1335 : // in tree.
1336 0 : NS_PRECONDITION(aFragment->IsNodeOfType(nsINode::eDOCUMENT_FRAGMENT),
1337 : "Argument was not DOM fragment.");
1338 0 : NS_PRECONDITION(!aFragment->IsInUncomposedDoc(), "The fragment is in doc?");
1339 :
1340 0 : mFullDocument = false;
1341 0 : SanitizeChildren(aFragment);
1342 0 : }
1343 :
1344 : void
1345 0 : nsTreeSanitizer::Sanitize(nsIDocument* aDocument)
1346 : {
1347 : // If you want to relax these preconditions, be sure to check the code in
1348 : // here that notifies / does not notify or that fires mutation events if
1349 : // in tree.
1350 : #ifdef DEBUG
1351 0 : NS_PRECONDITION(!aDocument->GetContainer(), "The document is in a shell.");
1352 0 : RefPtr<mozilla::dom::Element> root = aDocument->GetRootElement();
1353 0 : NS_PRECONDITION(root->IsHTMLElement(nsGkAtoms::html), "Not HTML root.");
1354 : #endif
1355 :
1356 0 : mFullDocument = true;
1357 0 : SanitizeChildren(aDocument);
1358 0 : }
1359 :
1360 : void
1361 0 : nsTreeSanitizer::SanitizeChildren(nsINode* aRoot)
1362 : {
1363 0 : nsIContent* node = aRoot->GetFirstChild();
1364 0 : while (node) {
1365 0 : if (node->IsElement()) {
1366 0 : mozilla::dom::Element* elt = node->AsElement();
1367 0 : mozilla::dom::NodeInfo* nodeInfo = node->NodeInfo();
1368 0 : nsIAtom* localName = nodeInfo->NameAtom();
1369 0 : int32_t ns = nodeInfo->NamespaceID();
1370 :
1371 0 : if (MustPrune(ns, localName, elt)) {
1372 0 : RemoveAllAttributes(node);
1373 0 : nsIContent* descendant = node;
1374 0 : while ((descendant = descendant->GetNextNode(node))) {
1375 0 : RemoveAllAttributes(descendant);
1376 : }
1377 0 : nsIContent* next = node->GetNextNonChildNode(aRoot);
1378 0 : node->RemoveFromParent();
1379 0 : node = next;
1380 0 : continue;
1381 : }
1382 0 : if (nsGkAtoms::style == localName) {
1383 : // If styles aren't allowed, style elements got pruned above. Even
1384 : // if styles are allowed, non-HTML, non-SVG style elements got pruned
1385 : // above.
1386 0 : NS_ASSERTION(ns == kNameSpaceID_XHTML || ns == kNameSpaceID_SVG,
1387 : "Should have only HTML or SVG here!");
1388 0 : nsAutoString styleText;
1389 0 : nsContentUtils::GetNodeTextContent(node, false, styleText);
1390 :
1391 0 : nsAutoString sanitizedStyle;
1392 0 : nsCOMPtr<nsIURI> baseURI = node->GetBaseURI();
1393 0 : if (SanitizeStyleSheet(styleText,
1394 : sanitizedStyle,
1395 : aRoot->OwnerDoc(),
1396 : baseURI)) {
1397 0 : nsContentUtils::SetNodeTextContent(node, sanitizedStyle, true);
1398 : } else {
1399 : // If the node had non-text child nodes, this operation zaps those.
1400 0 : nsContentUtils::SetNodeTextContent(node, styleText, true);
1401 : }
1402 0 : if (ns == kNameSpaceID_XHTML) {
1403 0 : SanitizeAttributes(elt,
1404 : sAttributesHTML,
1405 : (nsIAtom***)kURLAttributesHTML,
1406 : false,
1407 0 : mAllowStyles,
1408 0 : false);
1409 : } else {
1410 0 : SanitizeAttributes(elt,
1411 : sAttributesSVG,
1412 : (nsIAtom***)kURLAttributesSVG,
1413 : true,
1414 0 : mAllowStyles,
1415 0 : false);
1416 : }
1417 0 : node = node->GetNextNonChildNode(aRoot);
1418 0 : continue;
1419 : }
1420 0 : if (MustFlatten(ns, localName)) {
1421 0 : RemoveAllAttributes(node);
1422 0 : nsCOMPtr<nsIContent> next = node->GetNextNode(aRoot);
1423 0 : nsCOMPtr<nsIContent> parent = node->GetParent();
1424 0 : nsCOMPtr<nsIContent> child; // Must keep the child alive during move
1425 0 : ErrorResult rv;
1426 0 : while ((child = node->GetFirstChild())) {
1427 0 : nsCOMPtr<nsINode> refNode = node;
1428 0 : parent->InsertBefore(*child, refNode, rv);
1429 0 : if (rv.Failed()) {
1430 0 : break;
1431 : }
1432 : }
1433 0 : node->RemoveFromParent();
1434 0 : node = next;
1435 0 : continue;
1436 : }
1437 0 : NS_ASSERTION(ns == kNameSpaceID_XHTML ||
1438 : ns == kNameSpaceID_SVG ||
1439 : ns == kNameSpaceID_MathML,
1440 : "Should have only HTML, MathML or SVG here!");
1441 0 : if (ns == kNameSpaceID_XHTML) {
1442 0 : SanitizeAttributes(elt,
1443 : sAttributesHTML,
1444 : (nsIAtom***)kURLAttributesHTML,
1445 0 : false, mAllowStyles,
1446 0 : (nsGkAtoms::img == localName) &&
1447 0 : !mCidEmbedsOnly);
1448 0 : } else if (ns == kNameSpaceID_SVG) {
1449 0 : SanitizeAttributes(elt,
1450 : sAttributesSVG,
1451 : (nsIAtom***)kURLAttributesSVG,
1452 : true,
1453 0 : mAllowStyles,
1454 0 : false);
1455 : } else {
1456 : SanitizeAttributes(elt,
1457 : sAttributesMathML,
1458 : (nsIAtom***)kURLAttributesMathML,
1459 : true,
1460 : false,
1461 0 : false);
1462 : }
1463 0 : node = node->GetNextNode(aRoot);
1464 0 : continue;
1465 : }
1466 0 : NS_ASSERTION(!node->GetFirstChild(), "How come non-element node had kids?");
1467 0 : nsIContent* next = node->GetNextNonChildNode(aRoot);
1468 0 : if (!mAllowComments && node->IsNodeOfType(nsINode::eCOMMENT)) {
1469 0 : node->RemoveFromParent();
1470 : }
1471 0 : node = next;
1472 : }
1473 0 : }
1474 :
1475 : void
1476 0 : nsTreeSanitizer::RemoveAllAttributes(nsIContent* aElement)
1477 : {
1478 : const nsAttrName* attrName;
1479 0 : while ((attrName = aElement->GetAttrNameAt(0))) {
1480 0 : int32_t attrNs = attrName->NamespaceID();
1481 0 : nsCOMPtr<nsIAtom> attrLocal = attrName->LocalName();
1482 0 : aElement->UnsetAttr(attrNs, attrLocal, false);
1483 : }
1484 0 : }
1485 :
1486 : void
1487 0 : nsTreeSanitizer::InitializeStatics()
1488 : {
1489 0 : NS_PRECONDITION(!sElementsHTML, "Initializing a second time.");
1490 :
1491 0 : sElementsHTML = new nsTHashtable<nsISupportsHashKey>(ArrayLength(kElementsHTML));
1492 0 : for (uint32_t i = 0; kElementsHTML[i]; i++) {
1493 0 : sElementsHTML->PutEntry(*kElementsHTML[i]);
1494 : }
1495 :
1496 0 : sAttributesHTML = new nsTHashtable<nsISupportsHashKey>(ArrayLength(kAttributesHTML));
1497 0 : for (uint32_t i = 0; kAttributesHTML[i]; i++) {
1498 0 : sAttributesHTML->PutEntry(*kAttributesHTML[i]);
1499 : }
1500 :
1501 0 : sPresAttributesHTML = new nsTHashtable<nsISupportsHashKey>(ArrayLength(kPresAttributesHTML));
1502 0 : for (uint32_t i = 0; kPresAttributesHTML[i]; i++) {
1503 0 : sPresAttributesHTML->PutEntry(*kPresAttributesHTML[i]);
1504 : }
1505 :
1506 0 : sElementsSVG = new nsTHashtable<nsISupportsHashKey>(ArrayLength(kElementsSVG));
1507 0 : for (uint32_t i = 0; kElementsSVG[i]; i++) {
1508 0 : sElementsSVG->PutEntry(*kElementsSVG[i]);
1509 : }
1510 :
1511 0 : sAttributesSVG = new nsTHashtable<nsISupportsHashKey>(ArrayLength(kAttributesSVG));
1512 0 : for (uint32_t i = 0; kAttributesSVG[i]; i++) {
1513 0 : sAttributesSVG->PutEntry(*kAttributesSVG[i]);
1514 : }
1515 :
1516 0 : sElementsMathML = new nsTHashtable<nsISupportsHashKey>(ArrayLength(kElementsMathML));
1517 0 : for (uint32_t i = 0; kElementsMathML[i]; i++) {
1518 0 : sElementsMathML->PutEntry(*kElementsMathML[i]);
1519 : }
1520 :
1521 0 : sAttributesMathML = new nsTHashtable<nsISupportsHashKey>(ArrayLength(kAttributesMathML));
1522 0 : for (uint32_t i = 0; kAttributesMathML[i]; i++) {
1523 0 : sAttributesMathML->PutEntry(*kAttributesMathML[i]);
1524 : }
1525 :
1526 0 : nsCOMPtr<nsIPrincipal> principal = NullPrincipal::Create();
1527 0 : principal.forget(&sNullPrincipal);
1528 0 : }
1529 :
1530 : void
1531 0 : nsTreeSanitizer::ReleaseStatics()
1532 : {
1533 0 : delete sElementsHTML;
1534 0 : sElementsHTML = nullptr;
1535 :
1536 0 : delete sAttributesHTML;
1537 0 : sAttributesHTML = nullptr;
1538 :
1539 0 : delete sPresAttributesHTML;
1540 0 : sPresAttributesHTML = nullptr;
1541 :
1542 0 : delete sElementsSVG;
1543 0 : sElementsSVG = nullptr;
1544 :
1545 0 : delete sAttributesSVG;
1546 0 : sAttributesSVG = nullptr;
1547 :
1548 0 : delete sElementsMathML;
1549 0 : sElementsMathML = nullptr;
1550 :
1551 0 : delete sAttributesMathML;
1552 0 : sAttributesMathML = nullptr;
1553 :
1554 0 : NS_IF_RELEASE(sNullPrincipal);
1555 0 : }
|