LCOV - code coverage report
Current view: top level - dom/base - nsTreeSanitizer.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 343 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 14 0.0 %
Legend: Lines: hit not hit

          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 : }

Generated by: LCOV version 1.13