mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-18 15:55:36 +00:00
1f8589ab7c
The various AtomsTables in nsTreeSanitizer only contain static atoms. Knowing this, we can optimize things: - They can contain raw nsStaticAtom pointers instead of refcounted nsAtom pointers. - When looking up, we can/must first check if the atom we are looking for is static. If not, we know it can't be in the table. This is done by the new Contains() method. This change also lets us add more `const` to various places that interact with the tables. MozReview-Commit-ID: EFxWN2GU78L --HG-- extra : rebase_source : f2a0bdbb4c5179dd396476263e6a6b57adb13360
1612 lines
51 KiB
C++
1612 lines
51 KiB
C++
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#include "nsTreeSanitizer.h"
|
|
|
|
#include "mozilla/ArrayUtils.h"
|
|
#include "mozilla/BindingStyleRule.h"
|
|
#include "mozilla/DeclarationBlock.h"
|
|
#include "mozilla/DeclarationBlockInlines.h"
|
|
#include "mozilla/ServoDeclarationBlock.h"
|
|
#include "mozilla/StyleSheetInlines.h"
|
|
#include "mozilla/css/Rule.h"
|
|
#include "mozilla/dom/CSSRuleList.h"
|
|
#include "mozilla/dom/SRIMetadata.h"
|
|
#include "nsCSSParser.h"
|
|
#include "nsCSSPropertyID.h"
|
|
#include "nsUnicharInputStream.h"
|
|
#include "nsAttrName.h"
|
|
#include "nsIScriptError.h"
|
|
#include "nsIScriptSecurityManager.h"
|
|
#include "nsNetUtil.h"
|
|
#include "nsComponentManagerUtils.h"
|
|
#include "NullPrincipal.h"
|
|
#include "nsContentUtils.h"
|
|
#include "nsIParserUtils.h"
|
|
#include "nsIDocument.h"
|
|
#include "nsQueryObject.h"
|
|
|
|
using namespace mozilla;
|
|
using namespace mozilla::dom;
|
|
|
|
//
|
|
// Thanks to Mark Pilgrim and Sam Ruby for the initial whitelist
|
|
//
|
|
const nsStaticAtom* const kElementsHTML[] = {
|
|
nsGkAtoms::a,
|
|
nsGkAtoms::abbr,
|
|
nsGkAtoms::acronym,
|
|
nsGkAtoms::address,
|
|
nsGkAtoms::area,
|
|
nsGkAtoms::article,
|
|
nsGkAtoms::aside,
|
|
nsGkAtoms::audio,
|
|
nsGkAtoms::b,
|
|
nsGkAtoms::bdi,
|
|
nsGkAtoms::bdo,
|
|
nsGkAtoms::big,
|
|
nsGkAtoms::blockquote,
|
|
// body checked specially
|
|
nsGkAtoms::br,
|
|
nsGkAtoms::button,
|
|
nsGkAtoms::canvas,
|
|
nsGkAtoms::caption,
|
|
nsGkAtoms::center,
|
|
nsGkAtoms::cite,
|
|
nsGkAtoms::code,
|
|
nsGkAtoms::col,
|
|
nsGkAtoms::colgroup,
|
|
nsGkAtoms::datalist,
|
|
nsGkAtoms::dd,
|
|
nsGkAtoms::del,
|
|
nsGkAtoms::details,
|
|
nsGkAtoms::dfn,
|
|
nsGkAtoms::dir,
|
|
nsGkAtoms::div,
|
|
nsGkAtoms::dl,
|
|
nsGkAtoms::dt,
|
|
nsGkAtoms::em,
|
|
nsGkAtoms::fieldset,
|
|
nsGkAtoms::figcaption,
|
|
nsGkAtoms::figure,
|
|
nsGkAtoms::font,
|
|
nsGkAtoms::footer,
|
|
nsGkAtoms::form,
|
|
nsGkAtoms::h1,
|
|
nsGkAtoms::h2,
|
|
nsGkAtoms::h3,
|
|
nsGkAtoms::h4,
|
|
nsGkAtoms::h5,
|
|
nsGkAtoms::h6,
|
|
// head checked specially
|
|
nsGkAtoms::header,
|
|
nsGkAtoms::hgroup,
|
|
nsGkAtoms::hr,
|
|
// html checked specially
|
|
nsGkAtoms::i,
|
|
nsGkAtoms::img,
|
|
nsGkAtoms::input,
|
|
nsGkAtoms::ins,
|
|
nsGkAtoms::kbd,
|
|
nsGkAtoms::label,
|
|
nsGkAtoms::legend,
|
|
nsGkAtoms::li,
|
|
nsGkAtoms::link,
|
|
nsGkAtoms::listing,
|
|
nsGkAtoms::map,
|
|
nsGkAtoms::mark,
|
|
nsGkAtoms::menu,
|
|
nsGkAtoms::meta,
|
|
nsGkAtoms::meter,
|
|
nsGkAtoms::nav,
|
|
nsGkAtoms::nobr,
|
|
nsGkAtoms::noscript,
|
|
nsGkAtoms::ol,
|
|
nsGkAtoms::optgroup,
|
|
nsGkAtoms::option,
|
|
nsGkAtoms::output,
|
|
nsGkAtoms::p,
|
|
nsGkAtoms::pre,
|
|
nsGkAtoms::progress,
|
|
nsGkAtoms::q,
|
|
nsGkAtoms::rb,
|
|
nsGkAtoms::rp,
|
|
nsGkAtoms::rt,
|
|
nsGkAtoms::rtc,
|
|
nsGkAtoms::ruby,
|
|
nsGkAtoms::s,
|
|
nsGkAtoms::samp,
|
|
nsGkAtoms::section,
|
|
nsGkAtoms::select,
|
|
nsGkAtoms::small,
|
|
nsGkAtoms::source,
|
|
nsGkAtoms::span,
|
|
nsGkAtoms::strike,
|
|
nsGkAtoms::strong,
|
|
nsGkAtoms::sub,
|
|
nsGkAtoms::summary,
|
|
nsGkAtoms::sup,
|
|
// style checked specially
|
|
nsGkAtoms::table,
|
|
nsGkAtoms::tbody,
|
|
nsGkAtoms::td,
|
|
nsGkAtoms::textarea,
|
|
nsGkAtoms::tfoot,
|
|
nsGkAtoms::th,
|
|
nsGkAtoms::thead,
|
|
nsGkAtoms::time,
|
|
// title checked specially
|
|
nsGkAtoms::tr,
|
|
nsGkAtoms::track,
|
|
nsGkAtoms::tt,
|
|
nsGkAtoms::u,
|
|
nsGkAtoms::ul,
|
|
nsGkAtoms::var,
|
|
nsGkAtoms::video,
|
|
nsGkAtoms::wbr,
|
|
nullptr
|
|
};
|
|
|
|
const nsStaticAtom* const kAttributesHTML[] = {
|
|
nsGkAtoms::abbr,
|
|
nsGkAtoms::accept,
|
|
nsGkAtoms::acceptcharset,
|
|
nsGkAtoms::accesskey,
|
|
nsGkAtoms::action,
|
|
nsGkAtoms::alt,
|
|
nsGkAtoms::as,
|
|
nsGkAtoms::autocomplete,
|
|
nsGkAtoms::autofocus,
|
|
nsGkAtoms::autoplay,
|
|
nsGkAtoms::axis,
|
|
nsGkAtoms::_char,
|
|
nsGkAtoms::charoff,
|
|
nsGkAtoms::charset,
|
|
nsGkAtoms::checked,
|
|
nsGkAtoms::cite,
|
|
nsGkAtoms::_class,
|
|
nsGkAtoms::cols,
|
|
nsGkAtoms::colspan,
|
|
nsGkAtoms::content,
|
|
nsGkAtoms::contenteditable,
|
|
nsGkAtoms::contextmenu,
|
|
nsGkAtoms::controls,
|
|
nsGkAtoms::coords,
|
|
nsGkAtoms::crossorigin,
|
|
nsGkAtoms::datetime,
|
|
nsGkAtoms::dir,
|
|
nsGkAtoms::disabled,
|
|
nsGkAtoms::draggable,
|
|
nsGkAtoms::enctype,
|
|
nsGkAtoms::face,
|
|
nsGkAtoms::_for,
|
|
nsGkAtoms::frame,
|
|
nsGkAtoms::headers,
|
|
nsGkAtoms::height,
|
|
nsGkAtoms::hidden,
|
|
nsGkAtoms::high,
|
|
nsGkAtoms::href,
|
|
nsGkAtoms::hreflang,
|
|
nsGkAtoms::icon,
|
|
nsGkAtoms::id,
|
|
nsGkAtoms::integrity,
|
|
nsGkAtoms::ismap,
|
|
nsGkAtoms::itemid,
|
|
nsGkAtoms::itemprop,
|
|
nsGkAtoms::itemref,
|
|
nsGkAtoms::itemscope,
|
|
nsGkAtoms::itemtype,
|
|
nsGkAtoms::kind,
|
|
nsGkAtoms::label,
|
|
nsGkAtoms::lang,
|
|
nsGkAtoms::list_,
|
|
nsGkAtoms::longdesc,
|
|
nsGkAtoms::loop,
|
|
nsGkAtoms::low,
|
|
nsGkAtoms::max,
|
|
nsGkAtoms::maxlength,
|
|
nsGkAtoms::media,
|
|
nsGkAtoms::method,
|
|
nsGkAtoms::min,
|
|
nsGkAtoms::minlength,
|
|
nsGkAtoms::multiple,
|
|
nsGkAtoms::muted,
|
|
nsGkAtoms::name,
|
|
nsGkAtoms::nohref,
|
|
nsGkAtoms::novalidate,
|
|
nsGkAtoms::nowrap,
|
|
nsGkAtoms::open,
|
|
nsGkAtoms::optimum,
|
|
nsGkAtoms::pattern,
|
|
nsGkAtoms::placeholder,
|
|
nsGkAtoms::playbackrate,
|
|
nsGkAtoms::poster,
|
|
nsGkAtoms::preload,
|
|
nsGkAtoms::prompt,
|
|
nsGkAtoms::pubdate,
|
|
nsGkAtoms::radiogroup,
|
|
nsGkAtoms::readonly,
|
|
nsGkAtoms::rel,
|
|
nsGkAtoms::required,
|
|
nsGkAtoms::rev,
|
|
nsGkAtoms::reversed,
|
|
nsGkAtoms::role,
|
|
nsGkAtoms::rows,
|
|
nsGkAtoms::rowspan,
|
|
nsGkAtoms::rules,
|
|
nsGkAtoms::scoped,
|
|
nsGkAtoms::scope,
|
|
nsGkAtoms::selected,
|
|
nsGkAtoms::shape,
|
|
nsGkAtoms::span,
|
|
nsGkAtoms::spellcheck,
|
|
nsGkAtoms::src,
|
|
nsGkAtoms::srclang,
|
|
nsGkAtoms::start,
|
|
nsGkAtoms::summary,
|
|
nsGkAtoms::tabindex,
|
|
nsGkAtoms::target,
|
|
nsGkAtoms::title,
|
|
nsGkAtoms::type,
|
|
nsGkAtoms::usemap,
|
|
nsGkAtoms::value,
|
|
nsGkAtoms::width,
|
|
nsGkAtoms::wrap,
|
|
nullptr
|
|
};
|
|
|
|
const nsStaticAtom* const kPresAttributesHTML[] = {
|
|
nsGkAtoms::align,
|
|
nsGkAtoms::background,
|
|
nsGkAtoms::bgcolor,
|
|
nsGkAtoms::border,
|
|
nsGkAtoms::cellpadding,
|
|
nsGkAtoms::cellspacing,
|
|
nsGkAtoms::color,
|
|
nsGkAtoms::compact,
|
|
nsGkAtoms::clear,
|
|
nsGkAtoms::hspace,
|
|
nsGkAtoms::noshade,
|
|
nsGkAtoms::pointSize,
|
|
nsGkAtoms::size,
|
|
nsGkAtoms::valign,
|
|
nsGkAtoms::vspace,
|
|
nullptr
|
|
};
|
|
|
|
const nsStaticAtom* const kURLAttributesHTML[] = {
|
|
nsGkAtoms::action,
|
|
nsGkAtoms::href,
|
|
nsGkAtoms::src,
|
|
nsGkAtoms::longdesc,
|
|
nsGkAtoms::cite,
|
|
nsGkAtoms::background,
|
|
nullptr
|
|
};
|
|
|
|
const nsStaticAtom* const kElementsSVG[] = {
|
|
nsGkAtoms::a, // a
|
|
nsGkAtoms::circle, // circle
|
|
nsGkAtoms::clipPath, // clipPath
|
|
nsGkAtoms::colorProfile, // color-profile
|
|
nsGkAtoms::cursor, // cursor
|
|
nsGkAtoms::defs, // defs
|
|
nsGkAtoms::desc, // desc
|
|
nsGkAtoms::ellipse, // ellipse
|
|
nsGkAtoms::elevation, // elevation
|
|
nsGkAtoms::erode, // erode
|
|
nsGkAtoms::ex, // ex
|
|
nsGkAtoms::exact, // exact
|
|
nsGkAtoms::exponent, // exponent
|
|
nsGkAtoms::feBlend, // feBlend
|
|
nsGkAtoms::feColorMatrix, // feColorMatrix
|
|
nsGkAtoms::feComponentTransfer, // feComponentTransfer
|
|
nsGkAtoms::feComposite, // feComposite
|
|
nsGkAtoms::feConvolveMatrix, // feConvolveMatrix
|
|
nsGkAtoms::feDiffuseLighting, // feDiffuseLighting
|
|
nsGkAtoms::feDisplacementMap, // feDisplacementMap
|
|
nsGkAtoms::feDistantLight, // feDistantLight
|
|
nsGkAtoms::feDropShadow, // feDropShadow
|
|
nsGkAtoms::feFlood, // feFlood
|
|
nsGkAtoms::feFuncA, // feFuncA
|
|
nsGkAtoms::feFuncB, // feFuncB
|
|
nsGkAtoms::feFuncG, // feFuncG
|
|
nsGkAtoms::feFuncR, // feFuncR
|
|
nsGkAtoms::feGaussianBlur, // feGaussianBlur
|
|
nsGkAtoms::feImage, // feImage
|
|
nsGkAtoms::feMerge, // feMerge
|
|
nsGkAtoms::feMergeNode, // feMergeNode
|
|
nsGkAtoms::feMorphology, // feMorphology
|
|
nsGkAtoms::feOffset, // feOffset
|
|
nsGkAtoms::fePointLight, // fePointLight
|
|
nsGkAtoms::feSpecularLighting, // feSpecularLighting
|
|
nsGkAtoms::feSpotLight, // feSpotLight
|
|
nsGkAtoms::feTile, // feTile
|
|
nsGkAtoms::feTurbulence, // feTurbulence
|
|
nsGkAtoms::filter, // filter
|
|
nsGkAtoms::font, // font
|
|
nsGkAtoms::font_face, // font-face
|
|
nsGkAtoms::font_face_format, // font-face-format
|
|
nsGkAtoms::font_face_name, // font-face-name
|
|
nsGkAtoms::font_face_src, // font-face-src
|
|
nsGkAtoms::font_face_uri, // font-face-uri
|
|
nsGkAtoms::foreignObject, // foreignObject
|
|
nsGkAtoms::g, // g
|
|
// glyph
|
|
nsGkAtoms::glyphRef, // glyphRef
|
|
// hkern
|
|
nsGkAtoms::image, // image
|
|
nsGkAtoms::line, // line
|
|
nsGkAtoms::linearGradient, // linearGradient
|
|
nsGkAtoms::marker, // marker
|
|
nsGkAtoms::mask, // mask
|
|
nsGkAtoms::metadata, // metadata
|
|
nsGkAtoms::missingGlyph, // missingGlyph
|
|
nsGkAtoms::mpath, // mpath
|
|
nsGkAtoms::path, // path
|
|
nsGkAtoms::pattern, // pattern
|
|
nsGkAtoms::polygon, // polygon
|
|
nsGkAtoms::polyline, // polyline
|
|
nsGkAtoms::radialGradient, // radialGradient
|
|
nsGkAtoms::rect, // rect
|
|
nsGkAtoms::stop, // stop
|
|
nsGkAtoms::svg, // svg
|
|
nsGkAtoms::svgSwitch, // switch
|
|
nsGkAtoms::symbol, // symbol
|
|
nsGkAtoms::text, // text
|
|
nsGkAtoms::textPath, // textPath
|
|
nsGkAtoms::title, // title
|
|
nsGkAtoms::tref, // tref
|
|
nsGkAtoms::tspan, // tspan
|
|
nsGkAtoms::use, // use
|
|
nsGkAtoms::view, // view
|
|
// vkern
|
|
nullptr
|
|
};
|
|
|
|
const nsStaticAtom* const kAttributesSVG[] = {
|
|
// accent-height
|
|
nsGkAtoms::accumulate, // accumulate
|
|
nsGkAtoms::additive, // additive
|
|
nsGkAtoms::alignment_baseline, // alignment-baseline
|
|
// alphabetic
|
|
nsGkAtoms::amplitude, // amplitude
|
|
// arabic-form
|
|
// ascent
|
|
nsGkAtoms::attributeName, // attributeName
|
|
nsGkAtoms::attributeType, // attributeType
|
|
nsGkAtoms::azimuth, // azimuth
|
|
nsGkAtoms::baseFrequency, // baseFrequency
|
|
nsGkAtoms::baseline_shift, // baseline-shift
|
|
// baseProfile
|
|
// bbox
|
|
nsGkAtoms::begin, // begin
|
|
nsGkAtoms::bias, // bias
|
|
nsGkAtoms::by, // by
|
|
nsGkAtoms::calcMode, // calcMode
|
|
// cap-height
|
|
nsGkAtoms::_class, // class
|
|
nsGkAtoms::clip_path, // clip-path
|
|
nsGkAtoms::clip_rule, // clip-rule
|
|
nsGkAtoms::clipPathUnits, // clipPathUnits
|
|
nsGkAtoms::color, // color
|
|
nsGkAtoms::colorInterpolation, // color-interpolation
|
|
nsGkAtoms::colorInterpolationFilters, // color-interpolation-filters
|
|
nsGkAtoms::cursor, // cursor
|
|
nsGkAtoms::cx, // cx
|
|
nsGkAtoms::cy, // cy
|
|
nsGkAtoms::d, // d
|
|
// descent
|
|
nsGkAtoms::diffuseConstant, // diffuseConstant
|
|
nsGkAtoms::direction, // direction
|
|
nsGkAtoms::display, // display
|
|
nsGkAtoms::divisor, // divisor
|
|
nsGkAtoms::dominant_baseline, // dominant-baseline
|
|
nsGkAtoms::dur, // dur
|
|
nsGkAtoms::dx, // dx
|
|
nsGkAtoms::dy, // dy
|
|
nsGkAtoms::edgeMode, // edgeMode
|
|
nsGkAtoms::elevation, // elevation
|
|
// enable-background
|
|
nsGkAtoms::end, // end
|
|
nsGkAtoms::fill, // fill
|
|
nsGkAtoms::fill_opacity, // fill-opacity
|
|
nsGkAtoms::fill_rule, // fill-rule
|
|
nsGkAtoms::filter, // filter
|
|
nsGkAtoms::filterUnits, // filterUnits
|
|
nsGkAtoms::flood_color, // flood-color
|
|
nsGkAtoms::flood_opacity, // flood-opacity
|
|
// XXX focusable
|
|
nsGkAtoms::font, // font
|
|
nsGkAtoms::font_family, // font-family
|
|
nsGkAtoms::font_size, // font-size
|
|
nsGkAtoms::font_size_adjust, // font-size-adjust
|
|
nsGkAtoms::font_stretch, // font-stretch
|
|
nsGkAtoms::font_style, // font-style
|
|
nsGkAtoms::font_variant, // font-variant
|
|
nsGkAtoms::fontWeight, // font-weight
|
|
nsGkAtoms::format, // format
|
|
nsGkAtoms::from, // from
|
|
nsGkAtoms::fx, // fx
|
|
nsGkAtoms::fy, // fy
|
|
// g1
|
|
// g2
|
|
// glyph-name
|
|
// glyphRef
|
|
// glyph-orientation-horizontal
|
|
// glyph-orientation-vertical
|
|
nsGkAtoms::gradientTransform, // gradientTransform
|
|
nsGkAtoms::gradientUnits, // gradientUnits
|
|
nsGkAtoms::height, // height
|
|
// horiz-adv-x
|
|
// horiz-origin-x
|
|
// horiz-origin-y
|
|
nsGkAtoms::id, // id
|
|
// ideographic
|
|
nsGkAtoms::image_rendering, // image-rendering
|
|
nsGkAtoms::in, // in
|
|
nsGkAtoms::in2, // in2
|
|
nsGkAtoms::intercept, // intercept
|
|
// k
|
|
nsGkAtoms::k1, // k1
|
|
nsGkAtoms::k2, // k2
|
|
nsGkAtoms::k3, // k3
|
|
nsGkAtoms::k4, // k4
|
|
// kerning
|
|
nsGkAtoms::kernelMatrix, // kernelMatrix
|
|
nsGkAtoms::kernelUnitLength, // kernelUnitLength
|
|
nsGkAtoms::keyPoints, // keyPoints
|
|
nsGkAtoms::keySplines, // keySplines
|
|
nsGkAtoms::keyTimes, // keyTimes
|
|
nsGkAtoms::lang, // lang
|
|
// lengthAdjust
|
|
nsGkAtoms::letter_spacing, // letter-spacing
|
|
nsGkAtoms::lighting_color, // lighting-color
|
|
nsGkAtoms::limitingConeAngle, // limitingConeAngle
|
|
// local
|
|
nsGkAtoms::marker, // marker
|
|
nsGkAtoms::marker_end, // marker-end
|
|
nsGkAtoms::marker_mid, // marker-mid
|
|
nsGkAtoms::marker_start, // marker-start
|
|
nsGkAtoms::markerHeight, // markerHeight
|
|
nsGkAtoms::markerUnits, // markerUnits
|
|
nsGkAtoms::markerWidth, // markerWidth
|
|
nsGkAtoms::mask, // mask
|
|
nsGkAtoms::maskContentUnits, // maskContentUnits
|
|
nsGkAtoms::maskUnits, // maskUnits
|
|
// mathematical
|
|
nsGkAtoms::max, // max
|
|
nsGkAtoms::media, // media
|
|
nsGkAtoms::method, // method
|
|
nsGkAtoms::min, // min
|
|
nsGkAtoms::mode, // mode
|
|
nsGkAtoms::name, // name
|
|
nsGkAtoms::numOctaves, // numOctaves
|
|
nsGkAtoms::offset, // offset
|
|
nsGkAtoms::opacity, // opacity
|
|
nsGkAtoms::_operator, // operator
|
|
nsGkAtoms::order, // order
|
|
nsGkAtoms::orient, // orient
|
|
nsGkAtoms::orientation, // orientation
|
|
// origin
|
|
// overline-position
|
|
// overline-thickness
|
|
nsGkAtoms::overflow, // overflow
|
|
// panose-1
|
|
nsGkAtoms::path, // path
|
|
nsGkAtoms::pathLength, // pathLength
|
|
nsGkAtoms::patternContentUnits, // patternContentUnits
|
|
nsGkAtoms::patternTransform, // patternTransform
|
|
nsGkAtoms::patternUnits, // patternUnits
|
|
nsGkAtoms::pointer_events, // pointer-events XXX is this safe?
|
|
nsGkAtoms::points, // points
|
|
nsGkAtoms::pointsAtX, // pointsAtX
|
|
nsGkAtoms::pointsAtY, // pointsAtY
|
|
nsGkAtoms::pointsAtZ, // pointsAtZ
|
|
nsGkAtoms::preserveAlpha, // preserveAlpha
|
|
nsGkAtoms::preserveAspectRatio, // preserveAspectRatio
|
|
nsGkAtoms::primitiveUnits, // primitiveUnits
|
|
nsGkAtoms::r, // r
|
|
nsGkAtoms::radius, // radius
|
|
nsGkAtoms::refX, // refX
|
|
nsGkAtoms::refY, // refY
|
|
nsGkAtoms::repeatCount, // repeatCount
|
|
nsGkAtoms::repeatDur, // repeatDur
|
|
nsGkAtoms::requiredExtensions, // requiredExtensions
|
|
nsGkAtoms::requiredFeatures, // requiredFeatures
|
|
nsGkAtoms::restart, // restart
|
|
nsGkAtoms::result, // result
|
|
nsGkAtoms::rotate, // rotate
|
|
nsGkAtoms::rx, // rx
|
|
nsGkAtoms::ry, // ry
|
|
nsGkAtoms::scale, // scale
|
|
nsGkAtoms::seed, // seed
|
|
nsGkAtoms::shape_rendering, // shape-rendering
|
|
nsGkAtoms::slope, // slope
|
|
nsGkAtoms::spacing, // spacing
|
|
nsGkAtoms::specularConstant, // specularConstant
|
|
nsGkAtoms::specularExponent, // specularExponent
|
|
nsGkAtoms::spreadMethod, // spreadMethod
|
|
nsGkAtoms::startOffset, // startOffset
|
|
nsGkAtoms::stdDeviation, // stdDeviation
|
|
// stemh
|
|
// stemv
|
|
nsGkAtoms::stitchTiles, // stitchTiles
|
|
nsGkAtoms::stop_color, // stop-color
|
|
nsGkAtoms::stop_opacity, // stop-opacity
|
|
// strikethrough-position
|
|
// strikethrough-thickness
|
|
nsGkAtoms::string, // string
|
|
nsGkAtoms::stroke, // stroke
|
|
nsGkAtoms::stroke_dasharray, // stroke-dasharray
|
|
nsGkAtoms::stroke_dashoffset, // stroke-dashoffset
|
|
nsGkAtoms::stroke_linecap, // stroke-linecap
|
|
nsGkAtoms::stroke_linejoin, // stroke-linejoin
|
|
nsGkAtoms::stroke_miterlimit, // stroke-miterlimit
|
|
nsGkAtoms::stroke_opacity, // stroke-opacity
|
|
nsGkAtoms::stroke_width, // stroke-width
|
|
nsGkAtoms::surfaceScale, // surfaceScale
|
|
nsGkAtoms::systemLanguage, // systemLanguage
|
|
nsGkAtoms::tableValues, // tableValues
|
|
nsGkAtoms::target, // target
|
|
nsGkAtoms::targetX, // targetX
|
|
nsGkAtoms::targetY, // targetY
|
|
nsGkAtoms::text_anchor, // text-anchor
|
|
nsGkAtoms::text_decoration, // text-decoration
|
|
// textLength
|
|
nsGkAtoms::text_rendering, // text-rendering
|
|
nsGkAtoms::title, // title
|
|
nsGkAtoms::to, // to
|
|
nsGkAtoms::transform, // transform
|
|
nsGkAtoms::type, // type
|
|
// u1
|
|
// u2
|
|
// underline-position
|
|
// underline-thickness
|
|
// unicode
|
|
nsGkAtoms::unicode_bidi, // unicode-bidi
|
|
// unicode-range
|
|
// units-per-em
|
|
// v-alphabetic
|
|
// v-hanging
|
|
// v-ideographic
|
|
// v-mathematical
|
|
nsGkAtoms::values, // values
|
|
nsGkAtoms::vector_effect, // vector-effect
|
|
// vert-adv-y
|
|
// vert-origin-x
|
|
// vert-origin-y
|
|
nsGkAtoms::viewBox, // viewBox
|
|
nsGkAtoms::viewTarget, // viewTarget
|
|
nsGkAtoms::visibility, // visibility
|
|
nsGkAtoms::width, // width
|
|
// widths
|
|
nsGkAtoms::word_spacing, // word-spacing
|
|
nsGkAtoms::writing_mode, // writing-mode
|
|
nsGkAtoms::x, // x
|
|
// x-height
|
|
nsGkAtoms::x1, // x1
|
|
nsGkAtoms::x2, // x2
|
|
nsGkAtoms::xChannelSelector, // xChannelSelector
|
|
nsGkAtoms::y, // y
|
|
nsGkAtoms::y1, // y1
|
|
nsGkAtoms::y2, // y2
|
|
nsGkAtoms::yChannelSelector, // yChannelSelector
|
|
nsGkAtoms::z, // z
|
|
nsGkAtoms::zoomAndPan, // zoomAndPan
|
|
nullptr
|
|
};
|
|
|
|
const nsStaticAtom* const kURLAttributesSVG[] = {
|
|
nsGkAtoms::href,
|
|
nullptr
|
|
};
|
|
|
|
const nsStaticAtom* const kElementsMathML[] = {
|
|
nsGkAtoms::abs_, // abs
|
|
nsGkAtoms::_and, // and
|
|
nsGkAtoms::annotation_, // annotation
|
|
nsGkAtoms::annotation_xml_, // annotation-xml
|
|
nsGkAtoms::apply_, // apply
|
|
nsGkAtoms::approx_, // approx
|
|
nsGkAtoms::arccos_, // arccos
|
|
nsGkAtoms::arccosh_, // arccosh
|
|
nsGkAtoms::arccot_, // arccot
|
|
nsGkAtoms::arccoth_, // arccoth
|
|
nsGkAtoms::arccsc_, // arccsc
|
|
nsGkAtoms::arccsch_, // arccsch
|
|
nsGkAtoms::arcsec_, // arcsec
|
|
nsGkAtoms::arcsech_, // arcsech
|
|
nsGkAtoms::arcsin_, // arcsin
|
|
nsGkAtoms::arcsinh_, // arcsinh
|
|
nsGkAtoms::arctan_, // arctan
|
|
nsGkAtoms::arctanh_, // arctanh
|
|
nsGkAtoms::arg_, // arg
|
|
nsGkAtoms::bind_, // bind
|
|
nsGkAtoms::bvar_, // bvar
|
|
nsGkAtoms::card_, // card
|
|
nsGkAtoms::cartesianproduct_, // cartesianproduct
|
|
nsGkAtoms::cbytes_, // cbytes
|
|
nsGkAtoms::ceiling, // ceiling
|
|
nsGkAtoms::cerror_, // cerror
|
|
nsGkAtoms::ci_, // ci
|
|
nsGkAtoms::cn_, // cn
|
|
nsGkAtoms::codomain_, // codomain
|
|
nsGkAtoms::complexes_, // complexes
|
|
nsGkAtoms::compose_, // compose
|
|
nsGkAtoms::condition_, // condition
|
|
nsGkAtoms::conjugate_, // conjugate
|
|
nsGkAtoms::cos_, // cos
|
|
nsGkAtoms::cosh_, // cosh
|
|
nsGkAtoms::cot_, // cot
|
|
nsGkAtoms::coth_, // coth
|
|
nsGkAtoms::cs_, // cs
|
|
nsGkAtoms::csc_, // csc
|
|
nsGkAtoms::csch_, // csch
|
|
nsGkAtoms::csymbol_, // csymbol
|
|
nsGkAtoms::curl_, // curl
|
|
nsGkAtoms::declare, // declare
|
|
nsGkAtoms::degree_, // degree
|
|
nsGkAtoms::determinant_, // determinant
|
|
nsGkAtoms::diff_, // diff
|
|
nsGkAtoms::divergence_, // divergence
|
|
nsGkAtoms::divide_, // divide
|
|
nsGkAtoms::domain_, // domain
|
|
nsGkAtoms::domainofapplication_, // domainofapplication
|
|
nsGkAtoms::el, // el
|
|
nsGkAtoms::emptyset_, // emptyset
|
|
nsGkAtoms::eq_, // eq
|
|
nsGkAtoms::equivalent_, // equivalent
|
|
nsGkAtoms::eulergamma_, // eulergamma
|
|
nsGkAtoms::exists_, // exists
|
|
nsGkAtoms::exp_, // exp
|
|
nsGkAtoms::exponentiale_, // exponentiale
|
|
nsGkAtoms::factorial_, // factorial
|
|
nsGkAtoms::factorof_, // factorof
|
|
nsGkAtoms::_false, // false
|
|
nsGkAtoms::floor, // floor
|
|
nsGkAtoms::fn_, // fn
|
|
nsGkAtoms::forall_, // forall
|
|
nsGkAtoms::gcd_, // gcd
|
|
nsGkAtoms::geq_, // geq
|
|
nsGkAtoms::grad, // grad
|
|
nsGkAtoms::gt_, // gt
|
|
nsGkAtoms::ident_, // ident
|
|
nsGkAtoms::image, // image
|
|
nsGkAtoms::imaginary_, // imaginary
|
|
nsGkAtoms::imaginaryi_, // imaginaryi
|
|
nsGkAtoms::implies_, // implies
|
|
nsGkAtoms::in, // in
|
|
nsGkAtoms::infinity, // infinity
|
|
nsGkAtoms::int_, // int
|
|
nsGkAtoms::integers_, // integers
|
|
nsGkAtoms::intersect_, // intersect
|
|
nsGkAtoms::interval_, // interval
|
|
nsGkAtoms::inverse_, // inverse
|
|
nsGkAtoms::lambda_, // lambda
|
|
nsGkAtoms::laplacian_, // laplacian
|
|
nsGkAtoms::lcm_, // lcm
|
|
nsGkAtoms::leq_, // leq
|
|
nsGkAtoms::limit_, // limit
|
|
nsGkAtoms::list_, // list
|
|
nsGkAtoms::ln_, // ln
|
|
nsGkAtoms::log_, // log
|
|
nsGkAtoms::logbase_, // logbase
|
|
nsGkAtoms::lowlimit_, // lowlimit
|
|
nsGkAtoms::lt_, // lt
|
|
nsGkAtoms::maction_, // maction
|
|
nsGkAtoms::maligngroup_, // maligngroup
|
|
nsGkAtoms::malignmark_, // malignmark
|
|
nsGkAtoms::math, // math
|
|
nsGkAtoms::matrix, // matrix
|
|
nsGkAtoms::matrixrow_, // matrixrow
|
|
nsGkAtoms::max, // max
|
|
nsGkAtoms::mean_, // mean
|
|
nsGkAtoms::median_, // median
|
|
nsGkAtoms::menclose_, // menclose
|
|
nsGkAtoms::merror_, // merror
|
|
nsGkAtoms::mfenced_, // mfenced
|
|
nsGkAtoms::mfrac_, // mfrac
|
|
nsGkAtoms::mglyph_, // mglyph
|
|
nsGkAtoms::mi_, // mi
|
|
nsGkAtoms::min, // min
|
|
nsGkAtoms::minus_, // minus
|
|
nsGkAtoms::mlabeledtr_, // mlabeledtr
|
|
nsGkAtoms::mlongdiv_, // mlongdiv
|
|
nsGkAtoms::mmultiscripts_, // mmultiscripts
|
|
nsGkAtoms::mn_, // mn
|
|
nsGkAtoms::mo_, // mo
|
|
nsGkAtoms::mode, // mode
|
|
nsGkAtoms::moment_, // moment
|
|
nsGkAtoms::momentabout_, // momentabout
|
|
nsGkAtoms::mover_, // mover
|
|
nsGkAtoms::mpadded_, // mpadded
|
|
nsGkAtoms::mphantom_, // mphantom
|
|
nsGkAtoms::mprescripts_, // mprescripts
|
|
nsGkAtoms::mroot_, // mroot
|
|
nsGkAtoms::mrow_, // mrow
|
|
nsGkAtoms::ms_, // ms
|
|
nsGkAtoms::mscarries_, // mscarries
|
|
nsGkAtoms::mscarry_, // mscarry
|
|
nsGkAtoms::msgroup_, // msgroup
|
|
nsGkAtoms::msline_, // msline
|
|
nsGkAtoms::mspace_, // mspace
|
|
nsGkAtoms::msqrt_, // msqrt
|
|
nsGkAtoms::msrow_, // msrow
|
|
nsGkAtoms::mstack_, // mstack
|
|
nsGkAtoms::mstyle_, // mstyle
|
|
nsGkAtoms::msub_, // msub
|
|
nsGkAtoms::msubsup_, // msubsup
|
|
nsGkAtoms::msup_, // msup
|
|
nsGkAtoms::mtable_, // mtable
|
|
nsGkAtoms::mtd_, // mtd
|
|
nsGkAtoms::mtext_, // mtext
|
|
nsGkAtoms::mtr_, // mtr
|
|
nsGkAtoms::munder_, // munder
|
|
nsGkAtoms::munderover_, // munderover
|
|
nsGkAtoms::naturalnumbers_, // naturalnumbers
|
|
nsGkAtoms::neq_, // neq
|
|
nsGkAtoms::none, // none
|
|
nsGkAtoms::_not, // not
|
|
nsGkAtoms::notanumber_, // notanumber
|
|
nsGkAtoms::note_, // note
|
|
nsGkAtoms::notin_, // notin
|
|
nsGkAtoms::notprsubset_, // notprsubset
|
|
nsGkAtoms::notsubset_, // notsubset
|
|
nsGkAtoms::_or, // or
|
|
nsGkAtoms::otherwise, // otherwise
|
|
nsGkAtoms::outerproduct_, // outerproduct
|
|
nsGkAtoms::partialdiff_, // partialdiff
|
|
nsGkAtoms::pi_, // pi
|
|
nsGkAtoms::piece_, // piece
|
|
nsGkAtoms::piecewise_, // piecewise
|
|
nsGkAtoms::plus_, // plus
|
|
nsGkAtoms::power_, // power
|
|
nsGkAtoms::primes_, // primes
|
|
nsGkAtoms::product_, // product
|
|
nsGkAtoms::prsubset_, // prsubset
|
|
nsGkAtoms::quotient_, // quotient
|
|
nsGkAtoms::rationals_, // rationals
|
|
nsGkAtoms::real_, // real
|
|
nsGkAtoms::reals_, // reals
|
|
nsGkAtoms::reln_, // reln
|
|
nsGkAtoms::rem, // rem
|
|
nsGkAtoms::root_, // root
|
|
nsGkAtoms::scalarproduct_, // scalarproduct
|
|
nsGkAtoms::sdev_, // sdev
|
|
nsGkAtoms::sec_, // sec
|
|
nsGkAtoms::sech_, // sech
|
|
nsGkAtoms::selector_, // selector
|
|
nsGkAtoms::semantics_, // semantics
|
|
nsGkAtoms::sep_, // sep
|
|
nsGkAtoms::set, // set
|
|
nsGkAtoms::setdiff_, // setdiff
|
|
nsGkAtoms::share_, // share
|
|
nsGkAtoms::sin_, // sin
|
|
nsGkAtoms::sinh_, // sinh
|
|
nsGkAtoms::subset_, // subset
|
|
nsGkAtoms::sum, // sum
|
|
nsGkAtoms::tan_, // tan
|
|
nsGkAtoms::tanh_, // tanh
|
|
nsGkAtoms::tendsto_, // tendsto
|
|
nsGkAtoms::times_, // times
|
|
nsGkAtoms::transpose_, // transpose
|
|
nsGkAtoms::_true, // true
|
|
nsGkAtoms::union_, // union
|
|
nsGkAtoms::uplimit_, // uplimit
|
|
nsGkAtoms::variance_, // variance
|
|
nsGkAtoms::vector_, // vector
|
|
nsGkAtoms::vectorproduct_, // vectorproduct
|
|
nsGkAtoms::xor_, // xor
|
|
nullptr
|
|
};
|
|
|
|
const nsStaticAtom* const kAttributesMathML[] = {
|
|
nsGkAtoms::accent_, // accent
|
|
nsGkAtoms::accentunder_, // accentunder
|
|
nsGkAtoms::actiontype_, // actiontype
|
|
nsGkAtoms::align, // align
|
|
nsGkAtoms::alignmentscope_, // alignmentscope
|
|
nsGkAtoms::alt, // alt
|
|
nsGkAtoms::altimg_, // altimg
|
|
nsGkAtoms::altimg_height_, // altimg-height
|
|
nsGkAtoms::altimg_valign_, // altimg-valign
|
|
nsGkAtoms::altimg_width_, // altimg-width
|
|
nsGkAtoms::background, // background
|
|
nsGkAtoms::base, // base
|
|
nsGkAtoms::bevelled_, // bevelled
|
|
nsGkAtoms::cd_, // cd
|
|
nsGkAtoms::cdgroup_, // cdgroup
|
|
nsGkAtoms::charalign_, // charalign
|
|
nsGkAtoms::close, // close
|
|
nsGkAtoms::closure_, // closure
|
|
nsGkAtoms::color, // color
|
|
nsGkAtoms::columnalign_, // columnalign
|
|
nsGkAtoms::columnalignment_, // columnalignment
|
|
nsGkAtoms::columnlines_, // columnlines
|
|
nsGkAtoms::columnspacing_, // columnspacing
|
|
nsGkAtoms::columnspan_, // columnspan
|
|
nsGkAtoms::columnwidth_, // columnwidth
|
|
nsGkAtoms::crossout_, // crossout
|
|
nsGkAtoms::decimalpoint_, // decimalpoint
|
|
nsGkAtoms::definitionURL_, // definitionURL
|
|
nsGkAtoms::denomalign_, // denomalign
|
|
nsGkAtoms::depth_, // depth
|
|
nsGkAtoms::dir, // dir
|
|
nsGkAtoms::display, // display
|
|
nsGkAtoms::displaystyle_, // displaystyle
|
|
nsGkAtoms::edge_, // edge
|
|
nsGkAtoms::encoding, // encoding
|
|
nsGkAtoms::equalcolumns_, // equalcolumns
|
|
nsGkAtoms::equalrows_, // equalrows
|
|
nsGkAtoms::fence_, // fence
|
|
nsGkAtoms::fontfamily_, // fontfamily
|
|
nsGkAtoms::fontsize_, // fontsize
|
|
nsGkAtoms::fontstyle_, // fontstyle
|
|
nsGkAtoms::fontweight_, // fontweight
|
|
nsGkAtoms::form, // form
|
|
nsGkAtoms::frame, // frame
|
|
nsGkAtoms::framespacing_, // framespacing
|
|
nsGkAtoms::groupalign_, // groupalign
|
|
nsGkAtoms::height, // height
|
|
nsGkAtoms::href, // href
|
|
nsGkAtoms::id, // id
|
|
nsGkAtoms::indentalign_, // indentalign
|
|
nsGkAtoms::indentalignfirst_, // indentalignfirst
|
|
nsGkAtoms::indentalignlast_, // indentalignlast
|
|
nsGkAtoms::indentshift_, // indentshift
|
|
nsGkAtoms::indentshiftfirst_, // indentshiftfirst
|
|
nsGkAtoms::indenttarget_, // indenttarget
|
|
nsGkAtoms::index, // index
|
|
nsGkAtoms::integer, // integer
|
|
nsGkAtoms::largeop_, // largeop
|
|
nsGkAtoms::length, // length
|
|
nsGkAtoms::linebreak_, // linebreak
|
|
nsGkAtoms::linebreakmultchar_, // linebreakmultchar
|
|
nsGkAtoms::linebreakstyle_, // linebreakstyle
|
|
nsGkAtoms::linethickness_, // linethickness
|
|
nsGkAtoms::location_, // location
|
|
nsGkAtoms::longdivstyle_, // longdivstyle
|
|
nsGkAtoms::lquote_, // lquote
|
|
nsGkAtoms::lspace_, // lspace
|
|
nsGkAtoms::ltr, // ltr
|
|
nsGkAtoms::mathbackground_, // mathbackground
|
|
nsGkAtoms::mathcolor_, // mathcolor
|
|
nsGkAtoms::mathsize_, // mathsize
|
|
nsGkAtoms::mathvariant_, // mathvariant
|
|
nsGkAtoms::maxsize_, // maxsize
|
|
nsGkAtoms::minlabelspacing_, // minlabelspacing
|
|
nsGkAtoms::minsize_, // minsize
|
|
nsGkAtoms::movablelimits_, // movablelimits
|
|
nsGkAtoms::msgroup_, // msgroup
|
|
nsGkAtoms::name, // name
|
|
nsGkAtoms::newline, // newline
|
|
nsGkAtoms::notation_, // notation
|
|
nsGkAtoms::numalign_, // numalign
|
|
nsGkAtoms::number, // number
|
|
nsGkAtoms::open, // open
|
|
nsGkAtoms::order, // order
|
|
nsGkAtoms::other, // other
|
|
nsGkAtoms::overflow, // overflow
|
|
nsGkAtoms::position, // position
|
|
nsGkAtoms::role, // role
|
|
nsGkAtoms::rowalign_, // rowalign
|
|
nsGkAtoms::rowlines_, // rowlines
|
|
nsGkAtoms::rowspacing_, // rowspacing
|
|
nsGkAtoms::rowspan, // rowspan
|
|
nsGkAtoms::rquote_, // rquote
|
|
nsGkAtoms::rspace_, // rspace
|
|
nsGkAtoms::schemaLocation_, // schemaLocation
|
|
nsGkAtoms::scriptlevel_, // scriptlevel
|
|
nsGkAtoms::scriptminsize_, // scriptminsize
|
|
nsGkAtoms::scriptsize_, // scriptsize
|
|
nsGkAtoms::scriptsizemultiplier_, // scriptsizemultiplier
|
|
nsGkAtoms::selection_, // selection
|
|
nsGkAtoms::separator_, // separator
|
|
nsGkAtoms::separators_, // separators
|
|
nsGkAtoms::shift_, // shift
|
|
nsGkAtoms::side_, // side
|
|
nsGkAtoms::src, // src
|
|
nsGkAtoms::stackalign_, // stackalign
|
|
nsGkAtoms::stretchy_, // stretchy
|
|
nsGkAtoms::subscriptshift_, // subscriptshift
|
|
nsGkAtoms::superscriptshift_, // superscriptshift
|
|
nsGkAtoms::symmetric_, // symmetric
|
|
nsGkAtoms::type, // type
|
|
nsGkAtoms::voffset_, // voffset
|
|
nsGkAtoms::width, // width
|
|
nsGkAtoms::xref_, // xref
|
|
nullptr
|
|
};
|
|
|
|
const nsStaticAtom* const kURLAttributesMathML[] = {
|
|
nsGkAtoms::href,
|
|
nsGkAtoms::src,
|
|
nsGkAtoms::cdgroup_,
|
|
nsGkAtoms::altimg_,
|
|
nsGkAtoms::definitionURL_,
|
|
nullptr
|
|
};
|
|
|
|
nsTreeSanitizer::AtomsTable* nsTreeSanitizer::sElementsHTML = nullptr;
|
|
nsTreeSanitizer::AtomsTable* nsTreeSanitizer::sAttributesHTML = nullptr;
|
|
nsTreeSanitizer::AtomsTable* nsTreeSanitizer::sPresAttributesHTML = nullptr;
|
|
nsTreeSanitizer::AtomsTable* nsTreeSanitizer::sElementsSVG = nullptr;
|
|
nsTreeSanitizer::AtomsTable* nsTreeSanitizer::sAttributesSVG = nullptr;
|
|
nsTreeSanitizer::AtomsTable* nsTreeSanitizer::sElementsMathML = nullptr;
|
|
nsTreeSanitizer::AtomsTable* nsTreeSanitizer::sAttributesMathML = nullptr;
|
|
nsIPrincipal* nsTreeSanitizer::sNullPrincipal = nullptr;
|
|
|
|
nsTreeSanitizer::nsTreeSanitizer(uint32_t aFlags)
|
|
: mAllowStyles(aFlags & nsIParserUtils::SanitizerAllowStyle)
|
|
, mAllowComments(aFlags & nsIParserUtils::SanitizerAllowComments)
|
|
, mDropNonCSSPresentation(aFlags &
|
|
nsIParserUtils::SanitizerDropNonCSSPresentation)
|
|
, mDropForms(aFlags & nsIParserUtils::SanitizerDropForms)
|
|
, mCidEmbedsOnly(aFlags &
|
|
nsIParserUtils::SanitizerCidEmbedsOnly)
|
|
, mDropMedia(aFlags & nsIParserUtils::SanitizerDropMedia)
|
|
, mFullDocument(false)
|
|
, mLogRemovals(aFlags & nsIParserUtils::SanitizerLogRemovals)
|
|
{
|
|
if (mCidEmbedsOnly) {
|
|
// Sanitizing styles for external references is not supported.
|
|
mAllowStyles = false;
|
|
}
|
|
if (!sElementsHTML) {
|
|
// Initialize lazily to avoid having to initialize at all if the user
|
|
// doesn't paste HTML or load feeds.
|
|
InitializeStatics();
|
|
}
|
|
}
|
|
|
|
bool
|
|
nsTreeSanitizer::MustFlatten(int32_t aNamespace, nsAtom* aLocal)
|
|
{
|
|
if (aNamespace == kNameSpaceID_XHTML) {
|
|
if (mDropNonCSSPresentation && (nsGkAtoms::font == aLocal ||
|
|
nsGkAtoms::center == aLocal)) {
|
|
return true;
|
|
}
|
|
if (mDropForms && (nsGkAtoms::form == aLocal ||
|
|
nsGkAtoms::input == aLocal ||
|
|
nsGkAtoms::keygen == aLocal ||
|
|
nsGkAtoms::option == aLocal ||
|
|
nsGkAtoms::optgroup == aLocal)) {
|
|
return true;
|
|
}
|
|
if (mFullDocument && (nsGkAtoms::title == aLocal ||
|
|
nsGkAtoms::html == aLocal ||
|
|
nsGkAtoms::head == aLocal ||
|
|
nsGkAtoms::body == aLocal)) {
|
|
return false;
|
|
}
|
|
return !sElementsHTML->Contains(aLocal);
|
|
}
|
|
if (aNamespace == kNameSpaceID_SVG) {
|
|
if (mCidEmbedsOnly || mDropMedia) {
|
|
// Sanitizing CSS-based URL references inside SVG presentational
|
|
// attributes is not supported, so flattening for cid: embed case.
|
|
return true;
|
|
}
|
|
return !sElementsSVG->Contains(aLocal);
|
|
}
|
|
if (aNamespace == kNameSpaceID_MathML) {
|
|
return !sElementsMathML->Contains(aLocal);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool
|
|
nsTreeSanitizer::IsURL(const nsStaticAtom* const* aURLs, nsAtom* aLocalName)
|
|
{
|
|
const nsStaticAtom* atom;
|
|
while ((atom = *aURLs)) {
|
|
if (atom == aLocalName) {
|
|
return true;
|
|
}
|
|
++aURLs;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool
|
|
nsTreeSanitizer::MustPrune(int32_t aNamespace,
|
|
nsAtom* aLocal,
|
|
mozilla::dom::Element* aElement)
|
|
{
|
|
// To avoid attacks where a MathML script becomes something that gets
|
|
// serialized in a way that it parses back as an HTML script, let's just
|
|
// drop elements with the local name 'script' regardless of namespace.
|
|
if (nsGkAtoms::script == aLocal) {
|
|
return true;
|
|
}
|
|
if (aNamespace == kNameSpaceID_XHTML) {
|
|
if (nsGkAtoms::title == aLocal && !mFullDocument) {
|
|
// emulate the quirks of the old parser
|
|
return true;
|
|
}
|
|
if (mDropForms && (nsGkAtoms::select == aLocal ||
|
|
nsGkAtoms::button == aLocal ||
|
|
nsGkAtoms::datalist == aLocal)) {
|
|
return true;
|
|
}
|
|
if (mDropMedia && (nsGkAtoms::img == aLocal ||
|
|
nsGkAtoms::video == aLocal ||
|
|
nsGkAtoms::audio == aLocal ||
|
|
nsGkAtoms::source == aLocal)) {
|
|
return true;
|
|
}
|
|
if (nsGkAtoms::meta == aLocal &&
|
|
(aElement->HasAttr(kNameSpaceID_None, nsGkAtoms::charset) ||
|
|
aElement->HasAttr(kNameSpaceID_None, nsGkAtoms::httpEquiv))) {
|
|
// Throw away charset declarations even if they also have microdata
|
|
// which they can't validly have.
|
|
return true;
|
|
}
|
|
if (((!mFullDocument && nsGkAtoms::meta == aLocal) ||
|
|
nsGkAtoms::link == aLocal) &&
|
|
!(aElement->HasAttr(kNameSpaceID_None, nsGkAtoms::itemprop) ||
|
|
aElement->HasAttr(kNameSpaceID_None, nsGkAtoms::itemscope))) {
|
|
// emulate old behavior for non-Microdata <meta> and <link> presumably
|
|
// in <head>. <meta> and <link> are whitelisted in order to avoid
|
|
// corrupting Microdata when they appear in <body>. Note that
|
|
// SanitizeAttributes() will remove the rel attribute from <link> and
|
|
// the name attribute from <meta>.
|
|
return true;
|
|
}
|
|
}
|
|
if (mAllowStyles) {
|
|
if (nsGkAtoms::style == aLocal && !(aNamespace == kNameSpaceID_XHTML
|
|
|| aNamespace == kNameSpaceID_SVG)) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
if (nsGkAtoms::style == aLocal) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool
|
|
nsTreeSanitizer::SanitizeStyleDeclaration(DeclarationBlock* aDeclaration)
|
|
{
|
|
return aDeclaration->RemovePropertyByID(eCSSProperty__moz_binding);
|
|
}
|
|
|
|
bool
|
|
nsTreeSanitizer::SanitizeStyleSheet(const nsAString& aOriginal,
|
|
nsAString& aSanitized,
|
|
nsIDocument* aDocument,
|
|
nsIURI* aBaseURI)
|
|
{
|
|
nsresult rv = NS_OK;
|
|
aSanitized.Truncate();
|
|
// aSanitized will hold the permitted CSS text.
|
|
// -moz-binding is blacklisted.
|
|
bool didSanitize = false;
|
|
// Create a sheet to hold the parsed CSS
|
|
RefPtr<StyleSheet> sheet =
|
|
new ServoStyleSheet(mozilla::css::eAuthorSheetFeatures,
|
|
CORS_NONE, aDocument->GetReferrerPolicy(),
|
|
SRIMetadata());
|
|
sheet->SetURIs(aDocument->GetDocumentURI(), nullptr, aBaseURI);
|
|
sheet->SetPrincipal(aDocument->NodePrincipal());
|
|
sheet->AsServo()->ParseSheetSync(
|
|
aDocument->CSSLoader(), NS_ConvertUTF16toUTF8(aOriginal),
|
|
aDocument->GetDocumentURI(), aBaseURI, aDocument->NodePrincipal(),
|
|
/* aLoadData = */ nullptr, 0, aDocument->GetCompatibilityMode());
|
|
NS_ENSURE_SUCCESS(rv, true);
|
|
// Mark the sheet as complete.
|
|
MOZ_ASSERT(!sheet->HasForcedUniqueInner(),
|
|
"should not get a forced unique inner during parsing");
|
|
sheet->SetComplete();
|
|
// Loop through all the rules found in the CSS text
|
|
ErrorResult err;
|
|
RefPtr<dom::CSSRuleList> rules =
|
|
sheet->GetCssRules(*nsContentUtils::GetSystemPrincipal(), err);
|
|
err.SuppressException();
|
|
if (!rules) {
|
|
return true;
|
|
}
|
|
uint32_t ruleCount = rules->Length();
|
|
for (uint32_t i = 0; i < ruleCount; ++i) {
|
|
mozilla::css::Rule* rule = rules->Item(i);
|
|
if (!rule)
|
|
continue;
|
|
switch (rule->Type()) {
|
|
default:
|
|
didSanitize = true;
|
|
// Ignore these rule types.
|
|
break;
|
|
case CSSRuleBinding::NAMESPACE_RULE:
|
|
case CSSRuleBinding::FONT_FACE_RULE: {
|
|
// Append @namespace and @font-face rules verbatim.
|
|
nsAutoString cssText;
|
|
rule->GetCssText(cssText);
|
|
aSanitized.Append(cssText);
|
|
break;
|
|
}
|
|
case CSSRuleBinding::STYLE_RULE: {
|
|
// For style rules, we will just look for and remove the
|
|
// -moz-binding properties.
|
|
auto styleRule = static_cast<BindingStyleRule*>(rule);
|
|
DeclarationBlock* styleDecl = styleRule->GetDeclarationBlock();
|
|
MOZ_ASSERT(styleDecl);
|
|
if (SanitizeStyleDeclaration(styleDecl)) {
|
|
didSanitize = true;
|
|
}
|
|
nsAutoString decl;
|
|
styleRule->GetCssText(decl);
|
|
aSanitized.Append(decl);
|
|
}
|
|
}
|
|
}
|
|
if (didSanitize && mLogRemovals) {
|
|
LogMessage("Removed some rules and/or properties from stylesheet.", aDocument);
|
|
}
|
|
return didSanitize;
|
|
}
|
|
|
|
void
|
|
nsTreeSanitizer::SanitizeAttributes(mozilla::dom::Element* aElement,
|
|
AtomsTable* aAllowed,
|
|
const nsStaticAtom* const* aURLs,
|
|
bool aAllowXLink,
|
|
bool aAllowStyle,
|
|
bool aAllowDangerousSrc)
|
|
{
|
|
uint32_t ac = aElement->GetAttrCount();
|
|
|
|
for (int32_t i = ac - 1; i >= 0; --i) {
|
|
const nsAttrName* attrName = aElement->GetAttrNameAt(i);
|
|
int32_t attrNs = attrName->NamespaceID();
|
|
RefPtr<nsAtom> attrLocal = attrName->LocalName();
|
|
|
|
if (kNameSpaceID_None == attrNs) {
|
|
if (aAllowStyle && nsGkAtoms::style == attrLocal) {
|
|
nsAutoString value;
|
|
aElement->GetAttr(attrNs, attrLocal, value);
|
|
nsIDocument* document = aElement->OwnerDoc();
|
|
RefPtr<URLExtraData> urlExtra(aElement->GetURLDataForStyleAttr());
|
|
RefPtr<DeclarationBlock> decl =
|
|
ServoDeclarationBlock::FromCssText(
|
|
value,
|
|
urlExtra,
|
|
document->GetCompatibilityMode(),
|
|
document->CSSLoader());
|
|
if (decl) {
|
|
if (SanitizeStyleDeclaration(decl)) {
|
|
nsAutoString cleanValue;
|
|
decl->ToString(cleanValue);
|
|
aElement->SetAttr(kNameSpaceID_None,
|
|
nsGkAtoms::style,
|
|
cleanValue,
|
|
false);
|
|
if (mLogRemovals) {
|
|
LogMessage("Removed -moz-binding styling from element style attribute.",
|
|
aElement->OwnerDoc(), aElement);
|
|
}
|
|
}
|
|
}
|
|
continue;
|
|
}
|
|
if (aAllowDangerousSrc && nsGkAtoms::src == attrLocal) {
|
|
continue;
|
|
}
|
|
if (IsURL(aURLs, attrLocal)) {
|
|
if (SanitizeURL(aElement, attrNs, attrLocal)) {
|
|
// in case the attribute removal shuffled the attribute order, start
|
|
// the loop again.
|
|
--ac;
|
|
i = ac; // i will be decremented immediately thanks to the for loop
|
|
continue;
|
|
}
|
|
// else fall through to see if there's another reason to drop this
|
|
// attribute (in particular if the attribute is background="" on an
|
|
// HTML element)
|
|
}
|
|
if (!mDropNonCSSPresentation &&
|
|
(aAllowed == sAttributesHTML) && // element is HTML
|
|
sPresAttributesHTML->Contains(attrLocal)) {
|
|
continue;
|
|
}
|
|
if (aAllowed->Contains(attrLocal) &&
|
|
!((attrLocal == nsGkAtoms::rel &&
|
|
aElement->IsHTMLElement(nsGkAtoms::link)) ||
|
|
(!mFullDocument &&
|
|
attrLocal == nsGkAtoms::name &&
|
|
aElement->IsHTMLElement(nsGkAtoms::meta)))) {
|
|
// name="" and rel="" are whitelisted, but treat them as blacklisted
|
|
// for <meta name> (fragment case) and <link rel> (all cases) to avoid
|
|
// document-wide metadata or styling overrides with non-conforming
|
|
// <meta name itemprop> or
|
|
// <link rel itemprop>
|
|
continue;
|
|
}
|
|
const char16_t* localStr = attrLocal->GetUTF16String();
|
|
// Allow underscore to cater to the MCE editor library.
|
|
// Allow data-* on SVG and MathML, too, as a forward-compat measure.
|
|
if (*localStr == '_' || (attrLocal->GetLength() > 5 && localStr[0] == 'd'
|
|
&& localStr[1] == 'a' && localStr[2] == 't' && localStr[3] == 'a'
|
|
&& localStr[4] == '-')) {
|
|
continue;
|
|
}
|
|
// else not allowed
|
|
} else if (kNameSpaceID_XML == attrNs) {
|
|
if (nsGkAtoms::base == attrLocal) {
|
|
if (SanitizeURL(aElement, attrNs, attrLocal)) {
|
|
// in case the attribute removal shuffled the attribute order, start
|
|
// the loop again.
|
|
--ac;
|
|
i = ac; // i will be decremented immediately thanks to the for loop
|
|
}
|
|
continue;
|
|
}
|
|
if (nsGkAtoms::lang == attrLocal || nsGkAtoms::space == attrLocal) {
|
|
continue;
|
|
}
|
|
// else not allowed
|
|
} else if (aAllowXLink && kNameSpaceID_XLink == attrNs) {
|
|
if (nsGkAtoms::href == attrLocal) {
|
|
if (SanitizeURL(aElement, attrNs, attrLocal)) {
|
|
// in case the attribute removal shuffled the attribute order, start
|
|
// the loop again.
|
|
--ac;
|
|
i = ac; // i will be decremented immediately thanks to the for loop
|
|
}
|
|
continue;
|
|
}
|
|
if (nsGkAtoms::type == attrLocal || nsGkAtoms::title == attrLocal
|
|
|| nsGkAtoms::show == attrLocal || nsGkAtoms::actuate == attrLocal) {
|
|
continue;
|
|
}
|
|
// else not allowed
|
|
}
|
|
aElement->UnsetAttr(kNameSpaceID_None, attrLocal, false);
|
|
if (mLogRemovals) {
|
|
LogMessage("Removed unsafe attribute.", aElement->OwnerDoc(),
|
|
aElement, attrLocal);
|
|
}
|
|
// in case the attribute removal shuffled the attribute order, start the
|
|
// loop again.
|
|
--ac;
|
|
i = ac; // i will be decremented immediately thanks to the for loop
|
|
}
|
|
|
|
// If we've got HTML audio or video, add the controls attribute, because
|
|
// otherwise the content is unplayable with scripts removed.
|
|
if (aElement->IsAnyOfHTMLElements(nsGkAtoms::video, nsGkAtoms::audio)) {
|
|
aElement->SetAttr(kNameSpaceID_None,
|
|
nsGkAtoms::controls,
|
|
EmptyString(),
|
|
false);
|
|
}
|
|
}
|
|
|
|
bool
|
|
nsTreeSanitizer::SanitizeURL(mozilla::dom::Element* aElement,
|
|
int32_t aNamespace,
|
|
nsAtom* aLocalName)
|
|
{
|
|
nsAutoString value;
|
|
aElement->GetAttr(aNamespace, aLocalName, value);
|
|
|
|
// Get value and remove mandatory quotes
|
|
static const char* kWhitespace = "\n\r\t\b";
|
|
const nsAString& v =
|
|
nsContentUtils::TrimCharsInSet(kWhitespace, value);
|
|
// Fragment-only url cannot be harmful.
|
|
if (!v.IsEmpty() && v.First() == u'#') {
|
|
return false;
|
|
}
|
|
|
|
nsIScriptSecurityManager* secMan = nsContentUtils::GetSecurityManager();
|
|
uint32_t flags = nsIScriptSecurityManager::DISALLOW_INHERIT_PRINCIPAL;
|
|
|
|
nsCOMPtr<nsIURI> baseURI = aElement->GetBaseURI();
|
|
nsCOMPtr<nsIURI> attrURI;
|
|
nsresult rv = NS_NewURI(getter_AddRefs(attrURI), v, nullptr, baseURI);
|
|
if (NS_SUCCEEDED(rv)) {
|
|
if (mCidEmbedsOnly &&
|
|
kNameSpaceID_None == aNamespace) {
|
|
if (nsGkAtoms::src == aLocalName || nsGkAtoms::background == aLocalName) {
|
|
// comm-central uses a hack that makes nsIURIs created with cid: specs
|
|
// actually have an about:blank spec. Therefore, nsIURI facilities are
|
|
// useless for cid: when comm-central code is participating.
|
|
if (!(v.Length() > 4 &&
|
|
(v[0] == 'c' || v[0] == 'C') &&
|
|
(v[1] == 'i' || v[1] == 'I') &&
|
|
(v[2] == 'd' || v[2] == 'D') &&
|
|
v[3] == ':')) {
|
|
rv = NS_ERROR_FAILURE;
|
|
}
|
|
} else if (nsGkAtoms::cdgroup_ == aLocalName ||
|
|
nsGkAtoms::altimg_ == aLocalName ||
|
|
nsGkAtoms::definitionURL_ == aLocalName) {
|
|
// Gecko doesn't fetch these now and shouldn't in the future, but
|
|
// in case someone goofs with these in the future, let's drop them.
|
|
rv = NS_ERROR_FAILURE;
|
|
} else {
|
|
rv = secMan->CheckLoadURIWithPrincipal(sNullPrincipal, attrURI, flags);
|
|
}
|
|
} else {
|
|
rv = secMan->CheckLoadURIWithPrincipal(sNullPrincipal, attrURI, flags);
|
|
}
|
|
}
|
|
if (NS_FAILED(rv)) {
|
|
aElement->UnsetAttr(aNamespace, aLocalName, false);
|
|
if (mLogRemovals) {
|
|
LogMessage("Removed unsafe URI from element attribute.",
|
|
aElement->OwnerDoc(), aElement, aLocalName);
|
|
}
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void
|
|
nsTreeSanitizer::Sanitize(nsIContent* aFragment)
|
|
{
|
|
// If you want to relax these preconditions, be sure to check the code in
|
|
// here that notifies / does not notify or that fires mutation events if
|
|
// in tree.
|
|
NS_PRECONDITION(aFragment->IsNodeOfType(nsINode::eDOCUMENT_FRAGMENT),
|
|
"Argument was not DOM fragment.");
|
|
NS_PRECONDITION(!aFragment->IsInUncomposedDoc(), "The fragment is in doc?");
|
|
|
|
mFullDocument = false;
|
|
SanitizeChildren(aFragment);
|
|
}
|
|
|
|
void
|
|
nsTreeSanitizer::Sanitize(nsIDocument* aDocument)
|
|
{
|
|
// If you want to relax these preconditions, be sure to check the code in
|
|
// here that notifies / does not notify or that fires mutation events if
|
|
// in tree.
|
|
#ifdef DEBUG
|
|
NS_PRECONDITION(!aDocument->GetContainer(), "The document is in a shell.");
|
|
RefPtr<mozilla::dom::Element> root = aDocument->GetRootElement();
|
|
NS_PRECONDITION(root->IsHTMLElement(nsGkAtoms::html), "Not HTML root.");
|
|
#endif
|
|
|
|
mFullDocument = true;
|
|
SanitizeChildren(aDocument);
|
|
}
|
|
|
|
void
|
|
nsTreeSanitizer::SanitizeChildren(nsINode* aRoot)
|
|
{
|
|
nsIContent* node = aRoot->GetFirstChild();
|
|
while (node) {
|
|
if (node->IsElement()) {
|
|
mozilla::dom::Element* elt = node->AsElement();
|
|
mozilla::dom::NodeInfo* nodeInfo = node->NodeInfo();
|
|
nsAtom* localName = nodeInfo->NameAtom();
|
|
int32_t ns = nodeInfo->NamespaceID();
|
|
|
|
if (MustPrune(ns, localName, elt)) {
|
|
if (mLogRemovals) {
|
|
LogMessage("Removing unsafe node.", elt->OwnerDoc(), elt);
|
|
}
|
|
RemoveAllAttributes(elt);
|
|
nsIContent* descendant = node;
|
|
while ((descendant = descendant->GetNextNode(node))) {
|
|
if (descendant->IsElement()) {
|
|
RemoveAllAttributes(descendant->AsElement());
|
|
}
|
|
}
|
|
nsIContent* next = node->GetNextNonChildNode(aRoot);
|
|
node->RemoveFromParent();
|
|
node = next;
|
|
continue;
|
|
}
|
|
if (nsGkAtoms::style == localName) {
|
|
// If styles aren't allowed, style elements got pruned above. Even
|
|
// if styles are allowed, non-HTML, non-SVG style elements got pruned
|
|
// above.
|
|
NS_ASSERTION(ns == kNameSpaceID_XHTML || ns == kNameSpaceID_SVG,
|
|
"Should have only HTML or SVG here!");
|
|
nsAutoString styleText;
|
|
nsContentUtils::GetNodeTextContent(node, false, styleText);
|
|
|
|
nsAutoString sanitizedStyle;
|
|
nsCOMPtr<nsIURI> baseURI = node->GetBaseURI();
|
|
if (SanitizeStyleSheet(styleText,
|
|
sanitizedStyle,
|
|
aRoot->OwnerDoc(),
|
|
baseURI)) {
|
|
nsContentUtils::SetNodeTextContent(node, sanitizedStyle, true);
|
|
} else {
|
|
// If the node had non-text child nodes, this operation zaps those.
|
|
//XXXgijs: if we're logging, we should theoretically report about
|
|
// this, but this way of removing those items doesn't allow for that
|
|
// to happen. Seems less likely to be a problem for actual chrome
|
|
// consumers though.
|
|
nsContentUtils::SetNodeTextContent(node, styleText, true);
|
|
}
|
|
if (ns == kNameSpaceID_XHTML) {
|
|
SanitizeAttributes(elt,
|
|
sAttributesHTML,
|
|
kURLAttributesHTML,
|
|
false,
|
|
mAllowStyles,
|
|
false);
|
|
} else {
|
|
SanitizeAttributes(elt,
|
|
sAttributesSVG,
|
|
kURLAttributesSVG,
|
|
true,
|
|
mAllowStyles,
|
|
false);
|
|
}
|
|
node = node->GetNextNonChildNode(aRoot);
|
|
continue;
|
|
}
|
|
if (MustFlatten(ns, localName)) {
|
|
if (mLogRemovals) {
|
|
LogMessage("Flattening unsafe node (descendants are preserved).",
|
|
elt->OwnerDoc(), elt);
|
|
}
|
|
RemoveAllAttributes(elt);
|
|
nsCOMPtr<nsIContent> next = node->GetNextNode(aRoot);
|
|
nsCOMPtr<nsIContent> parent = node->GetParent();
|
|
nsCOMPtr<nsIContent> child; // Must keep the child alive during move
|
|
ErrorResult rv;
|
|
while ((child = node->GetFirstChild())) {
|
|
nsCOMPtr<nsINode> refNode = node;
|
|
parent->InsertBefore(*child, refNode, rv);
|
|
if (rv.Failed()) {
|
|
break;
|
|
}
|
|
}
|
|
node->RemoveFromParent();
|
|
node = next;
|
|
continue;
|
|
}
|
|
NS_ASSERTION(ns == kNameSpaceID_XHTML ||
|
|
ns == kNameSpaceID_SVG ||
|
|
ns == kNameSpaceID_MathML,
|
|
"Should have only HTML, MathML or SVG here!");
|
|
if (ns == kNameSpaceID_XHTML) {
|
|
SanitizeAttributes(elt,
|
|
sAttributesHTML,
|
|
kURLAttributesHTML,
|
|
false, mAllowStyles,
|
|
(nsGkAtoms::img == localName) &&
|
|
!mCidEmbedsOnly);
|
|
} else if (ns == kNameSpaceID_SVG) {
|
|
SanitizeAttributes(elt,
|
|
sAttributesSVG,
|
|
kURLAttributesSVG,
|
|
true,
|
|
mAllowStyles,
|
|
false);
|
|
} else {
|
|
SanitizeAttributes(elt,
|
|
sAttributesMathML,
|
|
kURLAttributesMathML,
|
|
true,
|
|
false,
|
|
false);
|
|
}
|
|
node = node->GetNextNode(aRoot);
|
|
continue;
|
|
}
|
|
NS_ASSERTION(!node->GetFirstChild(), "How come non-element node had kids?");
|
|
nsIContent* next = node->GetNextNonChildNode(aRoot);
|
|
if (!mAllowComments && node->IsNodeOfType(nsINode::eCOMMENT)) {
|
|
node->RemoveFromParent();
|
|
}
|
|
node = next;
|
|
}
|
|
}
|
|
|
|
void
|
|
nsTreeSanitizer::RemoveAllAttributes(Element* aElement)
|
|
{
|
|
const nsAttrName* attrName;
|
|
while ((attrName = aElement->GetAttrNameAt(0))) {
|
|
int32_t attrNs = attrName->NamespaceID();
|
|
RefPtr<nsAtom> attrLocal = attrName->LocalName();
|
|
aElement->UnsetAttr(attrNs, attrLocal, false);
|
|
}
|
|
}
|
|
|
|
void
|
|
nsTreeSanitizer::LogMessage(const char* aMessage, nsIDocument* aDoc,
|
|
Element* aElement, nsAtom* aAttr)
|
|
{
|
|
if (mLogRemovals) {
|
|
nsAutoString msg;
|
|
msg.Assign(NS_ConvertASCIItoUTF16(aMessage));
|
|
if (aElement) {
|
|
msg.Append(NS_LITERAL_STRING(" Element: ") + aElement->LocalName() +
|
|
NS_LITERAL_STRING("."));
|
|
}
|
|
if (aAttr) {
|
|
msg.Append(NS_LITERAL_STRING(" Attribute: ") +
|
|
nsDependentAtomString(aAttr) + NS_LITERAL_STRING("."));
|
|
}
|
|
|
|
nsContentUtils::ReportToConsoleNonLocalized(
|
|
msg, nsIScriptError::warningFlag, NS_LITERAL_CSTRING("DOM"), aDoc);
|
|
}
|
|
}
|
|
|
|
void
|
|
nsTreeSanitizer::InitializeStatics()
|
|
{
|
|
NS_PRECONDITION(!sElementsHTML, "Initializing a second time.");
|
|
|
|
sElementsHTML = new AtomsTable(ArrayLength(kElementsHTML));
|
|
for (uint32_t i = 0; kElementsHTML[i]; i++) {
|
|
sElementsHTML->PutEntry(kElementsHTML[i]);
|
|
}
|
|
|
|
sAttributesHTML = new AtomsTable(ArrayLength(kAttributesHTML));
|
|
for (uint32_t i = 0; kAttributesHTML[i]; i++) {
|
|
sAttributesHTML->PutEntry(kAttributesHTML[i]);
|
|
}
|
|
|
|
sPresAttributesHTML = new AtomsTable(ArrayLength(kPresAttributesHTML));
|
|
for (uint32_t i = 0; kPresAttributesHTML[i]; i++) {
|
|
sPresAttributesHTML->PutEntry(kPresAttributesHTML[i]);
|
|
}
|
|
|
|
sElementsSVG = new AtomsTable(ArrayLength(kElementsSVG));
|
|
for (uint32_t i = 0; kElementsSVG[i]; i++) {
|
|
sElementsSVG->PutEntry(kElementsSVG[i]);
|
|
}
|
|
|
|
sAttributesSVG = new AtomsTable(ArrayLength(kAttributesSVG));
|
|
for (uint32_t i = 0; kAttributesSVG[i]; i++) {
|
|
sAttributesSVG->PutEntry(kAttributesSVG[i]);
|
|
}
|
|
|
|
sElementsMathML = new AtomsTable(ArrayLength(kElementsMathML));
|
|
for (uint32_t i = 0; kElementsMathML[i]; i++) {
|
|
sElementsMathML->PutEntry(kElementsMathML[i]);
|
|
}
|
|
|
|
sAttributesMathML = new AtomsTable(ArrayLength(kAttributesMathML));
|
|
for (uint32_t i = 0; kAttributesMathML[i]; i++) {
|
|
sAttributesMathML->PutEntry(kAttributesMathML[i]);
|
|
}
|
|
|
|
nsCOMPtr<nsIPrincipal> principal = NullPrincipal::CreateWithoutOriginAttributes();
|
|
principal.forget(&sNullPrincipal);
|
|
}
|
|
|
|
void
|
|
nsTreeSanitizer::ReleaseStatics()
|
|
{
|
|
delete sElementsHTML;
|
|
sElementsHTML = nullptr;
|
|
|
|
delete sAttributesHTML;
|
|
sAttributesHTML = nullptr;
|
|
|
|
delete sPresAttributesHTML;
|
|
sPresAttributesHTML = nullptr;
|
|
|
|
delete sElementsSVG;
|
|
sElementsSVG = nullptr;
|
|
|
|
delete sAttributesSVG;
|
|
sAttributesSVG = nullptr;
|
|
|
|
delete sElementsMathML;
|
|
sElementsMathML = nullptr;
|
|
|
|
delete sAttributesMathML;
|
|
sAttributesMathML = nullptr;
|
|
|
|
NS_IF_RELEASE(sNullPrincipal);
|
|
}
|