зеркало из https://github.com/mozilla/gecko-dev.git
1516 строки
56 KiB
C++
1516 строки
56 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/StyleSheetInlines.h"
|
|
#include "mozilla/css/Rule.h"
|
|
#include "mozilla/dom/CSSRuleList.h"
|
|
#include "mozilla/dom/DocumentFragment.h"
|
|
#include "mozilla/dom/SRIMetadata.h"
|
|
#include "mozilla/NullPrincipal.h"
|
|
#include "nsCSSPropertyID.h"
|
|
#include "nsUnicharInputStream.h"
|
|
#include "nsAttrName.h"
|
|
#include "nsIScriptError.h"
|
|
#include "nsIScriptSecurityManager.h"
|
|
#include "nsNetUtil.h"
|
|
#include "nsComponentManagerUtils.h"
|
|
#include "nsContentUtils.h"
|
|
#include "nsIParserUtils.h"
|
|
#include "mozilla/dom/Document.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[] = {
|
|
// clang-format off
|
|
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::keygen,
|
|
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
|
|
// clang-format on
|
|
};
|
|
|
|
const nsStaticAtom* const kAttributesHTML[] = {
|
|
// clang-format off
|
|
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
|
|
// clang-format on
|
|
};
|
|
|
|
const nsStaticAtom* const kPresAttributesHTML[] = {
|
|
// clang-format off
|
|
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
|
|
// clang-format on
|
|
};
|
|
|
|
// List of HTML attributes with URLs that the
|
|
// browser will fetch. Should be kept in sync with
|
|
// https://html.spec.whatwg.org/multipage/indices.html#attributes-3
|
|
const nsStaticAtom* const kURLAttributesHTML[] = {
|
|
// clang-format off
|
|
nsGkAtoms::action,
|
|
nsGkAtoms::href,
|
|
nsGkAtoms::src,
|
|
nsGkAtoms::longdesc,
|
|
nsGkAtoms::cite,
|
|
nsGkAtoms::background,
|
|
nsGkAtoms::formaction,
|
|
nsGkAtoms::data,
|
|
nsGkAtoms::ping,
|
|
nsGkAtoms::poster,
|
|
nullptr
|
|
// clang-format on
|
|
};
|
|
|
|
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::transform_origin, // transform-origin
|
|
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[] = {
|
|
// clang-format off
|
|
nsGkAtoms::href,
|
|
nsGkAtoms::src,
|
|
nsGkAtoms::cdgroup_,
|
|
nsGkAtoms::altimg_,
|
|
nsGkAtoms::definitionURL_,
|
|
nullptr
|
|
// clang-format on
|
|
};
|
|
|
|
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),
|
|
mOnlyConditionalCSS(aFlags &
|
|
nsIParserUtils::SanitizerRemoveOnlyConditionalCSS) {
|
|
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();
|
|
}
|
|
/* Ensure SanitizerRemoveOnlyConditionalCSS isn't combined with any
|
|
* flags, except SanitizerLogRemovals. */
|
|
MOZ_ASSERT(!mOnlyConditionalCSS ||
|
|
0 ==
|
|
(aFlags & ~(nsIParserUtils::SanitizerRemoveOnlyConditionalCSS |
|
|
nsIParserUtils::SanitizerLogRemovals)));
|
|
}
|
|
|
|
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::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;
|
|
}
|
|
|
|
void nsTreeSanitizer::SanitizeStyleSheet(const nsAString& aOriginal,
|
|
nsAString& aSanitized,
|
|
Document* aDocument,
|
|
nsIURI* aBaseURI) {
|
|
aSanitized.Truncate();
|
|
|
|
NS_ConvertUTF16toUTF8 style(aOriginal);
|
|
RefPtr<nsIReferrerInfo> referrer =
|
|
ReferrerInfo::CreateForInternalCSSResources(aDocument);
|
|
auto extraData =
|
|
MakeRefPtr<URLExtraData>(aBaseURI, referrer, aDocument->NodePrincipal());
|
|
auto sanitizationKind = mOnlyConditionalCSS
|
|
? StyleSanitizationKind::NoConditionalRules
|
|
: StyleSanitizationKind::Standard;
|
|
RefPtr<RawServoStyleSheetContents> contents =
|
|
Servo_StyleSheet_FromUTF8Bytes(
|
|
/* loader = */ nullptr,
|
|
/* stylesheet = */ nullptr,
|
|
/* load_data = */ nullptr, &style,
|
|
css::SheetParsingMode::eAuthorSheetFeatures, extraData.get(),
|
|
/* line_number_offset = */ 0, aDocument->GetCompatibilityMode(),
|
|
/* reusable_sheets = */ nullptr,
|
|
/* use_counters = */ nullptr, StyleAllowImportRules::Yes,
|
|
sanitizationKind, &aSanitized)
|
|
.Consume();
|
|
|
|
if (mLogRemovals && aSanitized.Length() != aOriginal.Length()) {
|
|
LogMessage("Removed some rules and/or properties from stylesheet.",
|
|
aDocument);
|
|
}
|
|
}
|
|
|
|
template <size_t Len>
|
|
static bool UTF16StringStartsWith(const char16_t* aStr, uint32_t aLength,
|
|
const char16_t (&aNeedle)[Len]) {
|
|
MOZ_ASSERT(aNeedle[Len - 1] == '\0',
|
|
"needle should be a UTF-16 encoded string literal");
|
|
|
|
if (aLength < Len - 1) {
|
|
return false;
|
|
}
|
|
for (size_t i = 0; i < Len - 1; i++) {
|
|
if (aStr[i] != aNeedle[i]) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void nsTreeSanitizer::SanitizeAttributes(mozilla::dom::Element* aElement,
|
|
AllowedAttributes aAllowed) {
|
|
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 (aAllowed.mStyle && nsGkAtoms::style == attrLocal) {
|
|
continue;
|
|
}
|
|
if (aAllowed.mDangerousSrc && nsGkAtoms::src == attrLocal) {
|
|
continue;
|
|
}
|
|
if (IsURL(aAllowed.mURLs, 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.mNames == sAttributesHTML) && // element is HTML
|
|
sPresAttributesHTML->Contains(attrLocal)) {
|
|
continue;
|
|
}
|
|
if (aAllowed.mNames->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();
|
|
uint32_t localLen = attrLocal->GetLength();
|
|
// Allow underscore to cater to the MCE editor library.
|
|
// Allow data-* on SVG and MathML, too, as a forward-compat measure.
|
|
// Allow aria-* on all for simplicity.
|
|
if (UTF16StringStartsWith(localStr, localLen, u"_") ||
|
|
UTF16StringStartsWith(localStr, localLen, u"data-") ||
|
|
UTF16StringStartsWith(localStr, localLen, u"aria-")) {
|
|
continue;
|
|
}
|
|
// else not allowed
|
|
} else if (kNameSpaceID_XML == attrNs) {
|
|
if (nsGkAtoms::lang == attrLocal || nsGkAtoms::space == attrLocal) {
|
|
continue;
|
|
}
|
|
// else not allowed
|
|
} else if (aAllowed.mXLink && 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> attrURI;
|
|
nsresult rv =
|
|
NS_NewURI(getter_AddRefs(attrURI), v, nullptr, aElement->GetBaseURI());
|
|
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,
|
|
0);
|
|
}
|
|
} else {
|
|
rv = secMan->CheckLoadURIWithPrincipal(sNullPrincipal, attrURI, flags, 0);
|
|
}
|
|
}
|
|
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(DocumentFragment* 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.
|
|
MOZ_ASSERT(!aFragment->IsInUncomposedDoc(), "The fragment is in doc?");
|
|
|
|
mFullDocument = false;
|
|
SanitizeChildren(aFragment);
|
|
}
|
|
|
|
void nsTreeSanitizer::Sanitize(Document* 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
|
|
MOZ_ASSERT(!aDocument->GetContainer(), "The document is in a shell.");
|
|
RefPtr<mozilla::dom::Element> root = aDocument->GetRootElement();
|
|
MOZ_ASSERT(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 (!mOnlyConditionalCSS && 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 !mOnlyConditionalCSS check the following condition:
|
|
// 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) ||
|
|
mOnlyConditionalCSS,
|
|
"Should have only HTML or SVG here!");
|
|
nsAutoString styleText;
|
|
nsContentUtils::GetNodeTextContent(node, false, styleText);
|
|
|
|
nsAutoString sanitizedStyle;
|
|
SanitizeStyleSheet(styleText, sanitizedStyle, aRoot->OwnerDoc(),
|
|
node->GetBaseURI());
|
|
nsContentUtils::SetNodeTextContent(node, sanitizedStyle, true);
|
|
|
|
if (!mOnlyConditionalCSS) {
|
|
AllowedAttributes allowed;
|
|
allowed.mStyle = mAllowStyles;
|
|
if (ns == kNameSpaceID_XHTML) {
|
|
allowed.mNames = sAttributesHTML;
|
|
allowed.mURLs = kURLAttributesHTML;
|
|
SanitizeAttributes(elt, allowed);
|
|
} else {
|
|
allowed.mNames = sAttributesSVG;
|
|
allowed.mURLs = kURLAttributesSVG;
|
|
allowed.mXLink = true;
|
|
SanitizeAttributes(elt, allowed);
|
|
}
|
|
}
|
|
node = node->GetNextNonChildNode(aRoot);
|
|
continue;
|
|
}
|
|
if (!mOnlyConditionalCSS && 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;
|
|
}
|
|
if (!mOnlyConditionalCSS) {
|
|
NS_ASSERTION(ns == kNameSpaceID_XHTML || ns == kNameSpaceID_SVG ||
|
|
ns == kNameSpaceID_MathML,
|
|
"Should have only HTML, MathML or SVG here!");
|
|
AllowedAttributes allowed;
|
|
if (ns == kNameSpaceID_XHTML) {
|
|
allowed.mNames = sAttributesHTML;
|
|
allowed.mURLs = kURLAttributesHTML;
|
|
allowed.mStyle = mAllowStyles;
|
|
allowed.mDangerousSrc =
|
|
nsGkAtoms::img == localName && !mCidEmbedsOnly;
|
|
SanitizeAttributes(elt, allowed);
|
|
} else if (ns == kNameSpaceID_SVG) {
|
|
allowed.mNames = sAttributesSVG;
|
|
allowed.mURLs = kURLAttributesSVG;
|
|
allowed.mXLink = true;
|
|
allowed.mStyle = mAllowStyles;
|
|
SanitizeAttributes(elt, allowed);
|
|
} else {
|
|
allowed.mNames = sAttributesMathML;
|
|
allowed.mURLs = kURLAttributesMathML;
|
|
allowed.mXLink = true;
|
|
SanitizeAttributes(elt, allowed);
|
|
}
|
|
}
|
|
node = node->GetNextNode(aRoot);
|
|
continue;
|
|
}
|
|
NS_ASSERTION(!node->GetFirstChild(), "How come non-element node had kids?");
|
|
nsIContent* next = node->GetNextNonChildNode(aRoot);
|
|
if (!mOnlyConditionalCSS && (!mAllowComments && node->IsComment())) {
|
|
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, Document* 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() {
|
|
MOZ_ASSERT(!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);
|
|
}
|