content/base/src/nsTreeSanitizer.cpp

Thu, 15 Jan 2015 21:03:48 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 21:03:48 +0100
branch
TOR_BUG_9701
changeset 11
deefc01c0e14
permissions
-rw-r--r--

Integrate friendly tips from Tor colleagues to make (or not) 4.5 alpha 3;
This includes removal of overloaded (but unused) methods, and addition of
a overlooked call to DataStruct::SetData(nsISupports, uint32_t, bool.)

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

mercurial