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