content/base/src/nsTreeSanitizer.cpp

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

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

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

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

mercurial