1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/content/base/src/nsTreeSanitizer.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,1568 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* vim: set sw=2 ts=2 et tw=80: */ 1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +#include "mozilla/ArrayUtils.h" 1.11 + 1.12 +#include "nsTreeSanitizer.h" 1.13 +#include "nsCSSParser.h" 1.14 +#include "nsCSSProperty.h" 1.15 +#include "mozilla/css/Declaration.h" 1.16 +#include "mozilla/css/StyleRule.h" 1.17 +#include "mozilla/css/Rule.h" 1.18 +#include "nsUnicharInputStream.h" 1.19 +#include "nsCSSStyleSheet.h" 1.20 +#include "nsIDOMCSSRule.h" 1.21 +#include "nsAttrName.h" 1.22 +#include "nsIScriptSecurityManager.h" 1.23 +#include "nsNetUtil.h" 1.24 +#include "nsComponentManagerUtils.h" 1.25 +#include "nsNullPrincipal.h" 1.26 +#include "nsContentUtils.h" 1.27 +#include "nsIParserUtils.h" 1.28 +#include "nsIDocument.h" 1.29 + 1.30 +using namespace mozilla; 1.31 + 1.32 +// 1.33 +// Thanks to Mark Pilgrim and Sam Ruby for the initial whitelist 1.34 +// 1.35 +nsIAtom** const kElementsHTML[] = { 1.36 + &nsGkAtoms::a, 1.37 + &nsGkAtoms::abbr, 1.38 + &nsGkAtoms::acronym, 1.39 + &nsGkAtoms::address, 1.40 + &nsGkAtoms::area, 1.41 + &nsGkAtoms::article, 1.42 + &nsGkAtoms::aside, 1.43 + &nsGkAtoms::audio, 1.44 + &nsGkAtoms::b, 1.45 + &nsGkAtoms::bdi, 1.46 + &nsGkAtoms::bdo, 1.47 + &nsGkAtoms::big, 1.48 + &nsGkAtoms::blockquote, 1.49 + // body checked specially 1.50 + &nsGkAtoms::br, 1.51 + &nsGkAtoms::button, 1.52 + &nsGkAtoms::canvas, 1.53 + &nsGkAtoms::caption, 1.54 + &nsGkAtoms::center, 1.55 + &nsGkAtoms::cite, 1.56 + &nsGkAtoms::code, 1.57 + &nsGkAtoms::col, 1.58 + &nsGkAtoms::colgroup, 1.59 + &nsGkAtoms::command, 1.60 + &nsGkAtoms::datalist, 1.61 + &nsGkAtoms::dd, 1.62 + &nsGkAtoms::del, 1.63 + &nsGkAtoms::details, 1.64 + &nsGkAtoms::dfn, 1.65 + &nsGkAtoms::dir, 1.66 + &nsGkAtoms::div, 1.67 + &nsGkAtoms::dl, 1.68 + &nsGkAtoms::dt, 1.69 + &nsGkAtoms::em, 1.70 + &nsGkAtoms::fieldset, 1.71 + &nsGkAtoms::figcaption, 1.72 + &nsGkAtoms::figure, 1.73 + &nsGkAtoms::font, 1.74 + &nsGkAtoms::footer, 1.75 + &nsGkAtoms::form, 1.76 + &nsGkAtoms::h1, 1.77 + &nsGkAtoms::h2, 1.78 + &nsGkAtoms::h3, 1.79 + &nsGkAtoms::h4, 1.80 + &nsGkAtoms::h5, 1.81 + &nsGkAtoms::h6, 1.82 + // head checked specially 1.83 + &nsGkAtoms::header, 1.84 + &nsGkAtoms::hgroup, 1.85 + &nsGkAtoms::hr, 1.86 + // html checked specially 1.87 + &nsGkAtoms::i, 1.88 + &nsGkAtoms::img, 1.89 + &nsGkAtoms::input, 1.90 + &nsGkAtoms::ins, 1.91 + &nsGkAtoms::kbd, 1.92 + &nsGkAtoms::label, 1.93 + &nsGkAtoms::legend, 1.94 + &nsGkAtoms::li, 1.95 + &nsGkAtoms::link, 1.96 + &nsGkAtoms::listing, 1.97 + &nsGkAtoms::map, 1.98 + &nsGkAtoms::mark, 1.99 + &nsGkAtoms::menu, 1.100 + &nsGkAtoms::meta, 1.101 + &nsGkAtoms::meter, 1.102 + &nsGkAtoms::nav, 1.103 + &nsGkAtoms::nobr, 1.104 + &nsGkAtoms::noscript, 1.105 + &nsGkAtoms::ol, 1.106 + &nsGkAtoms::optgroup, 1.107 + &nsGkAtoms::option, 1.108 + &nsGkAtoms::output, 1.109 + &nsGkAtoms::p, 1.110 + &nsGkAtoms::pre, 1.111 + &nsGkAtoms::progress, 1.112 + &nsGkAtoms::q, 1.113 + &nsGkAtoms::rp, 1.114 + &nsGkAtoms::rt, 1.115 + &nsGkAtoms::ruby, 1.116 + &nsGkAtoms::s, 1.117 + &nsGkAtoms::samp, 1.118 + &nsGkAtoms::section, 1.119 + &nsGkAtoms::select, 1.120 + &nsGkAtoms::small, 1.121 + &nsGkAtoms::source, 1.122 + &nsGkAtoms::span, 1.123 + &nsGkAtoms::strike, 1.124 + &nsGkAtoms::strong, 1.125 + &nsGkAtoms::sub, 1.126 + &nsGkAtoms::summary, 1.127 + &nsGkAtoms::sup, 1.128 + // style checked specially 1.129 + &nsGkAtoms::table, 1.130 + &nsGkAtoms::tbody, 1.131 + &nsGkAtoms::td, 1.132 + &nsGkAtoms::textarea, 1.133 + &nsGkAtoms::tfoot, 1.134 + &nsGkAtoms::th, 1.135 + &nsGkAtoms::thead, 1.136 + &nsGkAtoms::time, 1.137 + // title checked specially 1.138 + &nsGkAtoms::tr, 1.139 + &nsGkAtoms::track, 1.140 + &nsGkAtoms::tt, 1.141 + &nsGkAtoms::u, 1.142 + &nsGkAtoms::ul, 1.143 + &nsGkAtoms::var, 1.144 + &nsGkAtoms::video, 1.145 + &nsGkAtoms::wbr, 1.146 + nullptr 1.147 +}; 1.148 + 1.149 +nsIAtom** const kAttributesHTML[] = { 1.150 + &nsGkAtoms::abbr, 1.151 + &nsGkAtoms::accept, 1.152 + &nsGkAtoms::acceptcharset, 1.153 + &nsGkAtoms::accesskey, 1.154 + &nsGkAtoms::action, 1.155 + &nsGkAtoms::alt, 1.156 + &nsGkAtoms::autocomplete, 1.157 + &nsGkAtoms::autofocus, 1.158 + &nsGkAtoms::autoplay, 1.159 + &nsGkAtoms::axis, 1.160 + &nsGkAtoms::_char, 1.161 + &nsGkAtoms::charoff, 1.162 + &nsGkAtoms::charset, 1.163 + &nsGkAtoms::checked, 1.164 + &nsGkAtoms::cite, 1.165 + &nsGkAtoms::_class, 1.166 + &nsGkAtoms::cols, 1.167 + &nsGkAtoms::colspan, 1.168 + &nsGkAtoms::content, 1.169 + &nsGkAtoms::contenteditable, 1.170 + &nsGkAtoms::contextmenu, 1.171 + &nsGkAtoms::controls, 1.172 + &nsGkAtoms::coords, 1.173 + &nsGkAtoms::datetime, 1.174 + &nsGkAtoms::dir, 1.175 + &nsGkAtoms::disabled, 1.176 + &nsGkAtoms::draggable, 1.177 + &nsGkAtoms::enctype, 1.178 + &nsGkAtoms::face, 1.179 + &nsGkAtoms::_for, 1.180 + &nsGkAtoms::frame, 1.181 + &nsGkAtoms::headers, 1.182 + &nsGkAtoms::height, 1.183 + &nsGkAtoms::hidden, 1.184 + &nsGkAtoms::high, 1.185 + &nsGkAtoms::href, 1.186 + &nsGkAtoms::hreflang, 1.187 + &nsGkAtoms::icon, 1.188 + &nsGkAtoms::id, 1.189 + &nsGkAtoms::ismap, 1.190 + &nsGkAtoms::itemid, 1.191 + &nsGkAtoms::itemprop, 1.192 + &nsGkAtoms::itemref, 1.193 + &nsGkAtoms::itemscope, 1.194 + &nsGkAtoms::itemtype, 1.195 + &nsGkAtoms::kind, 1.196 + &nsGkAtoms::label, 1.197 + &nsGkAtoms::lang, 1.198 + &nsGkAtoms::list, 1.199 + &nsGkAtoms::longdesc, 1.200 + &nsGkAtoms::loop, 1.201 + &nsGkAtoms::low, 1.202 + &nsGkAtoms::max, 1.203 + &nsGkAtoms::maxlength, 1.204 + &nsGkAtoms::media, 1.205 + &nsGkAtoms::method, 1.206 + &nsGkAtoms::min, 1.207 + &nsGkAtoms::mozdonotsend, 1.208 + &nsGkAtoms::multiple, 1.209 + &nsGkAtoms::muted, 1.210 + &nsGkAtoms::name, 1.211 + &nsGkAtoms::nohref, 1.212 + &nsGkAtoms::novalidate, 1.213 + &nsGkAtoms::nowrap, 1.214 + &nsGkAtoms::open, 1.215 + &nsGkAtoms::optimum, 1.216 + &nsGkAtoms::pattern, 1.217 + &nsGkAtoms::placeholder, 1.218 + &nsGkAtoms::playbackrate, 1.219 + &nsGkAtoms::poster, 1.220 + &nsGkAtoms::preload, 1.221 + &nsGkAtoms::prompt, 1.222 + &nsGkAtoms::pubdate, 1.223 + &nsGkAtoms::radiogroup, 1.224 + &nsGkAtoms::readonly, 1.225 + &nsGkAtoms::rel, 1.226 + &nsGkAtoms::required, 1.227 + &nsGkAtoms::rev, 1.228 + &nsGkAtoms::reversed, 1.229 + &nsGkAtoms::role, 1.230 + &nsGkAtoms::rows, 1.231 + &nsGkAtoms::rowspan, 1.232 + &nsGkAtoms::rules, 1.233 + &nsGkAtoms::scoped, 1.234 + &nsGkAtoms::scope, 1.235 + &nsGkAtoms::selected, 1.236 + &nsGkAtoms::shape, 1.237 + &nsGkAtoms::span, 1.238 + &nsGkAtoms::spellcheck, 1.239 + &nsGkAtoms::src, 1.240 + &nsGkAtoms::srclang, 1.241 + &nsGkAtoms::start, 1.242 + &nsGkAtoms::summary, 1.243 + &nsGkAtoms::tabindex, 1.244 + &nsGkAtoms::target, 1.245 + &nsGkAtoms::title, 1.246 + &nsGkAtoms::type, 1.247 + &nsGkAtoms::usemap, 1.248 + &nsGkAtoms::value, 1.249 + &nsGkAtoms::width, 1.250 + &nsGkAtoms::wrap, 1.251 + nullptr 1.252 +}; 1.253 + 1.254 +nsIAtom** const kPresAttributesHTML[] = { 1.255 + &nsGkAtoms::align, 1.256 + &nsGkAtoms::background, 1.257 + &nsGkAtoms::bgcolor, 1.258 + &nsGkAtoms::border, 1.259 + &nsGkAtoms::cellpadding, 1.260 + &nsGkAtoms::cellspacing, 1.261 + &nsGkAtoms::color, 1.262 + &nsGkAtoms::compact, 1.263 + &nsGkAtoms::clear, 1.264 + &nsGkAtoms::hspace, 1.265 + &nsGkAtoms::noshade, 1.266 + &nsGkAtoms::pointSize, 1.267 + &nsGkAtoms::size, 1.268 + &nsGkAtoms::valign, 1.269 + &nsGkAtoms::vspace, 1.270 + nullptr 1.271 +}; 1.272 + 1.273 +nsIAtom** const kURLAttributesHTML[] = { 1.274 + &nsGkAtoms::action, 1.275 + &nsGkAtoms::href, 1.276 + &nsGkAtoms::src, 1.277 + &nsGkAtoms::longdesc, 1.278 + &nsGkAtoms::cite, 1.279 + &nsGkAtoms::background, 1.280 + nullptr 1.281 +}; 1.282 + 1.283 +nsIAtom** const kElementsSVG[] = { 1.284 + &nsGkAtoms::a, // a 1.285 + &nsGkAtoms::altGlyph, // altGlyph 1.286 + &nsGkAtoms::altGlyphDef, // altGlyphDef 1.287 + &nsGkAtoms::altGlyphItem, // altGlyphItem 1.288 + &nsGkAtoms::animate, // animate 1.289 + &nsGkAtoms::animateColor, // animateColor 1.290 + &nsGkAtoms::animateMotion, // animateMotion 1.291 + &nsGkAtoms::animateTransform, // animateTransform 1.292 + &nsGkAtoms::circle, // circle 1.293 + &nsGkAtoms::clipPath, // clipPath 1.294 + &nsGkAtoms::colorProfile, // color-profile 1.295 + &nsGkAtoms::cursor, // cursor 1.296 + &nsGkAtoms::defs, // defs 1.297 + &nsGkAtoms::desc, // desc 1.298 + &nsGkAtoms::ellipse, // ellipse 1.299 + &nsGkAtoms::elevation, // elevation 1.300 + &nsGkAtoms::erode, // erode 1.301 + &nsGkAtoms::ex, // ex 1.302 + &nsGkAtoms::exact, // exact 1.303 + &nsGkAtoms::exponent, // exponent 1.304 + &nsGkAtoms::feBlend, // feBlend 1.305 + &nsGkAtoms::feColorMatrix, // feColorMatrix 1.306 + &nsGkAtoms::feComponentTransfer, // feComponentTransfer 1.307 + &nsGkAtoms::feComposite, // feComposite 1.308 + &nsGkAtoms::feConvolveMatrix, // feConvolveMatrix 1.309 + &nsGkAtoms::feDiffuseLighting, // feDiffuseLighting 1.310 + &nsGkAtoms::feDisplacementMap, // feDisplacementMap 1.311 + &nsGkAtoms::feDistantLight, // feDistantLight 1.312 + &nsGkAtoms::feDropShadow, // feDropShadow 1.313 + &nsGkAtoms::feFlood, // feFlood 1.314 + &nsGkAtoms::feFuncA, // feFuncA 1.315 + &nsGkAtoms::feFuncB, // feFuncB 1.316 + &nsGkAtoms::feFuncG, // feFuncG 1.317 + &nsGkAtoms::feFuncR, // feFuncR 1.318 + &nsGkAtoms::feGaussianBlur, // feGaussianBlur 1.319 + &nsGkAtoms::feImage, // feImage 1.320 + &nsGkAtoms::feMerge, // feMerge 1.321 + &nsGkAtoms::feMergeNode, // feMergeNode 1.322 + &nsGkAtoms::feMorphology, // feMorphology 1.323 + &nsGkAtoms::feOffset, // feOffset 1.324 + &nsGkAtoms::fePointLight, // fePointLight 1.325 + &nsGkAtoms::feSpecularLighting, // feSpecularLighting 1.326 + &nsGkAtoms::feSpotLight, // feSpotLight 1.327 + &nsGkAtoms::feTile, // feTile 1.328 + &nsGkAtoms::feTurbulence, // feTurbulence 1.329 + &nsGkAtoms::filter, // filter 1.330 + &nsGkAtoms::font, // font 1.331 + &nsGkAtoms::font_face, // font-face 1.332 + &nsGkAtoms::font_face_format, // font-face-format 1.333 + &nsGkAtoms::font_face_name, // font-face-name 1.334 + &nsGkAtoms::font_face_src, // font-face-src 1.335 + &nsGkAtoms::font_face_uri, // font-face-uri 1.336 + &nsGkAtoms::foreignObject, // foreignObject 1.337 + &nsGkAtoms::g, // g 1.338 + &nsGkAtoms::glyph, // glyph 1.339 + &nsGkAtoms::glyphRef, // glyphRef 1.340 + &nsGkAtoms::hkern, // hkern 1.341 + &nsGkAtoms::image, // image 1.342 + &nsGkAtoms::line, // line 1.343 + &nsGkAtoms::linearGradient, // linearGradient 1.344 + &nsGkAtoms::marker, // marker 1.345 + &nsGkAtoms::mask, // mask 1.346 + &nsGkAtoms::metadata, // metadata 1.347 + &nsGkAtoms::missingGlyph, // missingGlyph 1.348 + &nsGkAtoms::mpath, // mpath 1.349 + &nsGkAtoms::path, // path 1.350 + &nsGkAtoms::pattern, // pattern 1.351 + &nsGkAtoms::polygon, // polygon 1.352 + &nsGkAtoms::polyline, // polyline 1.353 + &nsGkAtoms::radialGradient, // radialGradient 1.354 + &nsGkAtoms::rect, // rect 1.355 + &nsGkAtoms::set, // set 1.356 + &nsGkAtoms::stop, // stop 1.357 + &nsGkAtoms::svg, // svg 1.358 + &nsGkAtoms::svgSwitch, // switch 1.359 + &nsGkAtoms::symbol, // symbol 1.360 + &nsGkAtoms::text, // text 1.361 + &nsGkAtoms::textPath, // textPath 1.362 + &nsGkAtoms::title, // title 1.363 + &nsGkAtoms::tref, // tref 1.364 + &nsGkAtoms::tspan, // tspan 1.365 + &nsGkAtoms::use, // use 1.366 + &nsGkAtoms::view, // view 1.367 + &nsGkAtoms::vkern, // vkern 1.368 + nullptr 1.369 +}; 1.370 + 1.371 +nsIAtom** const kAttributesSVG[] = { 1.372 + // accent-height 1.373 + &nsGkAtoms::accumulate, // accumulate 1.374 + &nsGkAtoms::additive, // additive 1.375 + &nsGkAtoms::alignment_baseline, // alignment-baseline 1.376 + // alphabetic 1.377 + &nsGkAtoms::amplitude, // amplitude 1.378 + // arabic-form 1.379 + // ascent 1.380 + &nsGkAtoms::attributeName, // attributeName 1.381 + &nsGkAtoms::attributeType, // attributeType 1.382 + &nsGkAtoms::azimuth, // azimuth 1.383 + &nsGkAtoms::baseFrequency, // baseFrequency 1.384 + &nsGkAtoms::baseline_shift, // baseline-shift 1.385 + // baseProfile 1.386 + // bbox 1.387 + &nsGkAtoms::begin, // begin 1.388 + &nsGkAtoms::bias, // bias 1.389 + &nsGkAtoms::by, // by 1.390 + &nsGkAtoms::calcMode, // calcMode 1.391 + // cap-height 1.392 + &nsGkAtoms::_class, // class 1.393 + &nsGkAtoms::clip_path, // clip-path 1.394 + &nsGkAtoms::clip_rule, // clip-rule 1.395 + &nsGkAtoms::clipPathUnits, // clipPathUnits 1.396 + &nsGkAtoms::color, // color 1.397 + &nsGkAtoms::colorInterpolation, // color-interpolation 1.398 + &nsGkAtoms::colorInterpolationFilters, // color-interpolation-filters 1.399 + // contentScriptType 1.400 + // contentStyleType 1.401 + &nsGkAtoms::cursor, // cursor 1.402 + &nsGkAtoms::cx, // cx 1.403 + &nsGkAtoms::cy, // cy 1.404 + &nsGkAtoms::d, // d 1.405 + // descent 1.406 + &nsGkAtoms::diffuseConstant, // diffuseConstant 1.407 + &nsGkAtoms::direction, // direction 1.408 + &nsGkAtoms::display, // display 1.409 + &nsGkAtoms::divisor, // divisor 1.410 + &nsGkAtoms::dominant_baseline, // dominant-baseline 1.411 + &nsGkAtoms::dur, // dur 1.412 + &nsGkAtoms::dx, // dx 1.413 + &nsGkAtoms::dy, // dy 1.414 + &nsGkAtoms::edgeMode, // edgeMode 1.415 + &nsGkAtoms::elevation, // elevation 1.416 + // enable-background 1.417 + &nsGkAtoms::end, // end 1.418 + &nsGkAtoms::fill, // fill 1.419 + &nsGkAtoms::fill_opacity, // fill-opacity 1.420 + &nsGkAtoms::fill_rule, // fill-rule 1.421 + &nsGkAtoms::filter, // filter 1.422 + &nsGkAtoms::filterRes, // filterRes 1.423 + &nsGkAtoms::filterUnits, // filterUnits 1.424 + &nsGkAtoms::flood_color, // flood-color 1.425 + &nsGkAtoms::flood_opacity, // flood-opacity 1.426 + // XXX focusable 1.427 + &nsGkAtoms::font, // font 1.428 + &nsGkAtoms::font_family, // font-family 1.429 + &nsGkAtoms::font_size, // font-size 1.430 + &nsGkAtoms::font_size_adjust, // font-size-adjust 1.431 + &nsGkAtoms::font_stretch, // font-stretch 1.432 + &nsGkAtoms::font_style, // font-style 1.433 + &nsGkAtoms::font_variant, // font-variant 1.434 + &nsGkAtoms::fontWeight, // font-weight 1.435 + &nsGkAtoms::format, // format 1.436 + &nsGkAtoms::from, // from 1.437 + &nsGkAtoms::fx, // fx 1.438 + &nsGkAtoms::fy, // fy 1.439 + // g1 1.440 + // g2 1.441 + // glyph-name 1.442 + // glyphRef 1.443 + &nsGkAtoms::glyph_orientation_horizontal, // glyph-orientation-horizontal 1.444 + &nsGkAtoms::glyph_orientation_vertical, // glyph-orientation-vertical 1.445 + &nsGkAtoms::gradientTransform, // gradientTransform 1.446 + &nsGkAtoms::gradientUnits, // gradientUnits 1.447 + &nsGkAtoms::height, // height 1.448 + // horiz-adv-x 1.449 + // horiz-origin-x 1.450 + // horiz-origin-y 1.451 + &nsGkAtoms::id, // id 1.452 + // ideographic 1.453 + &nsGkAtoms::image_rendering, // image-rendering 1.454 + &nsGkAtoms::in, // in 1.455 + &nsGkAtoms::in2, // in2 1.456 + &nsGkAtoms::intercept, // intercept 1.457 + // k 1.458 + &nsGkAtoms::k1, // k1 1.459 + &nsGkAtoms::k2, // k2 1.460 + &nsGkAtoms::k3, // k3 1.461 + &nsGkAtoms::k4, // k4 1.462 + &nsGkAtoms::kerning, // kerning 1.463 + &nsGkAtoms::kernelMatrix, // kernelMatrix 1.464 + &nsGkAtoms::kernelUnitLength, // kernelUnitLength 1.465 + &nsGkAtoms::keyPoints, // keyPoints 1.466 + &nsGkAtoms::keySplines, // keySplines 1.467 + &nsGkAtoms::keyTimes, // keyTimes 1.468 + &nsGkAtoms::lang, // lang 1.469 + // lengthAdjust 1.470 + &nsGkAtoms::letter_spacing, // letter-spacing 1.471 + &nsGkAtoms::lighting_color, // lighting-color 1.472 + &nsGkAtoms::limitingConeAngle, // limitingConeAngle 1.473 + // local 1.474 + &nsGkAtoms::marker, // marker 1.475 + &nsGkAtoms::marker_end, // marker-end 1.476 + &nsGkAtoms::marker_mid, // marker-mid 1.477 + &nsGkAtoms::marker_start, // marker-start 1.478 + &nsGkAtoms::markerHeight, // markerHeight 1.479 + &nsGkAtoms::markerUnits, // markerUnits 1.480 + &nsGkAtoms::markerWidth, // markerWidth 1.481 + &nsGkAtoms::mask, // mask 1.482 + &nsGkAtoms::maskContentUnits, // maskContentUnits 1.483 + &nsGkAtoms::maskUnits, // maskUnits 1.484 + // mathematical 1.485 + &nsGkAtoms::max, // max 1.486 + &nsGkAtoms::media, // media 1.487 + &nsGkAtoms::method, // method 1.488 + &nsGkAtoms::min, // min 1.489 + &nsGkAtoms::mode, // mode 1.490 + &nsGkAtoms::name, // name 1.491 + &nsGkAtoms::numOctaves, // numOctaves 1.492 + &nsGkAtoms::offset, // offset 1.493 + &nsGkAtoms::opacity, // opacity 1.494 + &nsGkAtoms::_operator, // operator 1.495 + &nsGkAtoms::order, // order 1.496 + &nsGkAtoms::orient, // orient 1.497 + &nsGkAtoms::orientation, // orientation 1.498 + // origin 1.499 + // overline-position 1.500 + // overline-thickness 1.501 + &nsGkAtoms::overflow, // overflow 1.502 + // panose-1 1.503 + &nsGkAtoms::path, // path 1.504 + &nsGkAtoms::pathLength, // pathLength 1.505 + &nsGkAtoms::patternContentUnits, // patternContentUnits 1.506 + &nsGkAtoms::patternTransform, // patternTransform 1.507 + &nsGkAtoms::patternUnits, // patternUnits 1.508 + &nsGkAtoms::pointer_events, // pointer-events XXX is this safe? 1.509 + &nsGkAtoms::points, // points 1.510 + &nsGkAtoms::pointsAtX, // pointsAtX 1.511 + &nsGkAtoms::pointsAtY, // pointsAtY 1.512 + &nsGkAtoms::pointsAtZ, // pointsAtZ 1.513 + &nsGkAtoms::preserveAlpha, // preserveAlpha 1.514 + &nsGkAtoms::preserveAspectRatio, // preserveAspectRatio 1.515 + &nsGkAtoms::primitiveUnits, // primitiveUnits 1.516 + &nsGkAtoms::r, // r 1.517 + &nsGkAtoms::radius, // radius 1.518 + &nsGkAtoms::refX, // refX 1.519 + &nsGkAtoms::refY, // refY 1.520 + &nsGkAtoms::repeatCount, // repeatCount 1.521 + &nsGkAtoms::repeatDur, // repeatDur 1.522 + &nsGkAtoms::requiredExtensions, // requiredExtensions 1.523 + &nsGkAtoms::requiredFeatures, // requiredFeatures 1.524 + &nsGkAtoms::restart, // restart 1.525 + &nsGkAtoms::result, // result 1.526 + &nsGkAtoms::rotate, // rotate 1.527 + &nsGkAtoms::rx, // rx 1.528 + &nsGkAtoms::ry, // ry 1.529 + &nsGkAtoms::scale, // scale 1.530 + &nsGkAtoms::seed, // seed 1.531 + &nsGkAtoms::shape_rendering, // shape-rendering 1.532 + &nsGkAtoms::slope, // slope 1.533 + &nsGkAtoms::spacing, // spacing 1.534 + &nsGkAtoms::specularConstant, // specularConstant 1.535 + &nsGkAtoms::specularExponent, // specularExponent 1.536 + &nsGkAtoms::spreadMethod, // spreadMethod 1.537 + &nsGkAtoms::startOffset, // startOffset 1.538 + &nsGkAtoms::stdDeviation, // stdDeviation 1.539 + // stemh 1.540 + // stemv 1.541 + &nsGkAtoms::stitchTiles, // stitchTiles 1.542 + &nsGkAtoms::stop_color, // stop-color 1.543 + &nsGkAtoms::stop_opacity, // stop-opacity 1.544 + // strikethrough-position 1.545 + // strikethrough-thickness 1.546 + &nsGkAtoms::string, // string 1.547 + &nsGkAtoms::stroke, // stroke 1.548 + &nsGkAtoms::stroke_dasharray, // stroke-dasharray 1.549 + &nsGkAtoms::stroke_dashoffset, // stroke-dashoffset 1.550 + &nsGkAtoms::stroke_linecap, // stroke-linecap 1.551 + &nsGkAtoms::stroke_linejoin, // stroke-linejoin 1.552 + &nsGkAtoms::stroke_miterlimit, // stroke-miterlimit 1.553 + &nsGkAtoms::stroke_opacity, // stroke-opacity 1.554 + &nsGkAtoms::stroke_width, // stroke-width 1.555 + &nsGkAtoms::surfaceScale, // surfaceScale 1.556 + &nsGkAtoms::systemLanguage, // systemLanguage 1.557 + &nsGkAtoms::tableValues, // tableValues 1.558 + &nsGkAtoms::target, // target 1.559 + &nsGkAtoms::targetX, // targetX 1.560 + &nsGkAtoms::targetY, // targetY 1.561 + &nsGkAtoms::text_anchor, // text-anchor 1.562 + &nsGkAtoms::text_decoration, // text-decoration 1.563 + // textLength 1.564 + &nsGkAtoms::text_rendering, // text-rendering 1.565 + &nsGkAtoms::title, // title 1.566 + &nsGkAtoms::to, // to 1.567 + &nsGkAtoms::transform, // transform 1.568 + &nsGkAtoms::type, // type 1.569 + // u1 1.570 + // u2 1.571 + // underline-position 1.572 + // underline-thickness 1.573 + // unicode 1.574 + &nsGkAtoms::unicode_bidi, // unicode-bidi 1.575 + // unicode-range 1.576 + // units-per-em 1.577 + // v-alphabetic 1.578 + // v-hanging 1.579 + // v-ideographic 1.580 + // v-mathematical 1.581 + &nsGkAtoms::values, // values 1.582 + &nsGkAtoms::vector_effect, // vector-effect 1.583 + // vert-adv-y 1.584 + // vert-origin-x 1.585 + // vert-origin-y 1.586 + &nsGkAtoms::viewBox, // viewBox 1.587 + &nsGkAtoms::viewTarget, // viewTarget 1.588 + &nsGkAtoms::visibility, // visibility 1.589 + &nsGkAtoms::width, // width 1.590 + // widths 1.591 + &nsGkAtoms::word_spacing, // word-spacing 1.592 + // writing-mode 1.593 + &nsGkAtoms::x, // x 1.594 + // x-height 1.595 + &nsGkAtoms::x1, // x1 1.596 + &nsGkAtoms::x2, // x2 1.597 + &nsGkAtoms::xChannelSelector, // xChannelSelector 1.598 + &nsGkAtoms::y, // y 1.599 + &nsGkAtoms::y1, // y1 1.600 + &nsGkAtoms::y2, // y2 1.601 + &nsGkAtoms::yChannelSelector, // yChannelSelector 1.602 + &nsGkAtoms::z, // z 1.603 + &nsGkAtoms::zoomAndPan, // zoomAndPan 1.604 + nullptr 1.605 +}; 1.606 + 1.607 +nsIAtom** const kURLAttributesSVG[] = { 1.608 + nullptr 1.609 +}; 1.610 + 1.611 +nsIAtom** const kElementsMathML[] = { 1.612 + &nsGkAtoms::abs_, // abs 1.613 + &nsGkAtoms::_and, // and 1.614 + &nsGkAtoms::annotation_, // annotation 1.615 + &nsGkAtoms::annotation_xml_, // annotation-xml 1.616 + &nsGkAtoms::apply_, // apply 1.617 + &nsGkAtoms::approx_, // approx 1.618 + &nsGkAtoms::arccos_, // arccos 1.619 + &nsGkAtoms::arccosh_, // arccosh 1.620 + &nsGkAtoms::arccot_, // arccot 1.621 + &nsGkAtoms::arccoth_, // arccoth 1.622 + &nsGkAtoms::arccsc_, // arccsc 1.623 + &nsGkAtoms::arccsch_, // arccsch 1.624 + &nsGkAtoms::arcsec_, // arcsec 1.625 + &nsGkAtoms::arcsech_, // arcsech 1.626 + &nsGkAtoms::arcsin_, // arcsin 1.627 + &nsGkAtoms::arcsinh_, // arcsinh 1.628 + &nsGkAtoms::arctan_, // arctan 1.629 + &nsGkAtoms::arctanh_, // arctanh 1.630 + &nsGkAtoms::arg_, // arg 1.631 + &nsGkAtoms::bind_, // bind 1.632 + &nsGkAtoms::bvar_, // bvar 1.633 + &nsGkAtoms::card_, // card 1.634 + &nsGkAtoms::cartesianproduct_, // cartesianproduct 1.635 + &nsGkAtoms::cbytes_, // cbytes 1.636 + &nsGkAtoms::ceiling, // ceiling 1.637 + &nsGkAtoms::cerror_, // cerror 1.638 + &nsGkAtoms::ci_, // ci 1.639 + &nsGkAtoms::cn_, // cn 1.640 + &nsGkAtoms::codomain_, // codomain 1.641 + &nsGkAtoms::complexes_, // complexes 1.642 + &nsGkAtoms::compose_, // compose 1.643 + &nsGkAtoms::condition_, // condition 1.644 + &nsGkAtoms::conjugate_, // conjugate 1.645 + &nsGkAtoms::cos_, // cos 1.646 + &nsGkAtoms::cosh_, // cosh 1.647 + &nsGkAtoms::cot_, // cot 1.648 + &nsGkAtoms::coth_, // coth 1.649 + &nsGkAtoms::cs_, // cs 1.650 + &nsGkAtoms::csc_, // csc 1.651 + &nsGkAtoms::csch_, // csch 1.652 + &nsGkAtoms::csymbol_, // csymbol 1.653 + &nsGkAtoms::curl_, // curl 1.654 + &nsGkAtoms::declare, // declare 1.655 + &nsGkAtoms::degree_, // degree 1.656 + &nsGkAtoms::determinant_, // determinant 1.657 + &nsGkAtoms::diff_, // diff 1.658 + &nsGkAtoms::divergence_, // divergence 1.659 + &nsGkAtoms::divide_, // divide 1.660 + &nsGkAtoms::domain_, // domain 1.661 + &nsGkAtoms::domainofapplication_, // domainofapplication 1.662 + &nsGkAtoms::el_, // el 1.663 + &nsGkAtoms::emptyset_, // emptyset 1.664 + &nsGkAtoms::eq_, // eq 1.665 + &nsGkAtoms::equivalent_, // equivalent 1.666 + &nsGkAtoms::eulergamma_, // eulergamma 1.667 + &nsGkAtoms::exists_, // exists 1.668 + &nsGkAtoms::exp_, // exp 1.669 + &nsGkAtoms::exponentiale_, // exponentiale 1.670 + &nsGkAtoms::factorial_, // factorial 1.671 + &nsGkAtoms::factorof_, // factorof 1.672 + &nsGkAtoms::_false, // false 1.673 + &nsGkAtoms::floor, // floor 1.674 + &nsGkAtoms::fn_, // fn 1.675 + &nsGkAtoms::forall_, // forall 1.676 + &nsGkAtoms::gcd_, // gcd 1.677 + &nsGkAtoms::geq_, // geq 1.678 + &nsGkAtoms::grad, // grad 1.679 + &nsGkAtoms::gt_, // gt 1.680 + &nsGkAtoms::ident_, // ident 1.681 + &nsGkAtoms::image, // image 1.682 + &nsGkAtoms::imaginary_, // imaginary 1.683 + &nsGkAtoms::imaginaryi_, // imaginaryi 1.684 + &nsGkAtoms::implies_, // implies 1.685 + &nsGkAtoms::in, // in 1.686 + &nsGkAtoms::infinity, // infinity 1.687 + &nsGkAtoms::int_, // int 1.688 + &nsGkAtoms::integers_, // integers 1.689 + &nsGkAtoms::intersect_, // intersect 1.690 + &nsGkAtoms::interval_, // interval 1.691 + &nsGkAtoms::inverse_, // inverse 1.692 + &nsGkAtoms::lambda_, // lambda 1.693 + &nsGkAtoms::laplacian_, // laplacian 1.694 + &nsGkAtoms::lcm_, // lcm 1.695 + &nsGkAtoms::leq_, // leq 1.696 + &nsGkAtoms::limit_, // limit 1.697 + &nsGkAtoms::list_, // list 1.698 + &nsGkAtoms::ln_, // ln 1.699 + &nsGkAtoms::log_, // log 1.700 + &nsGkAtoms::logbase_, // logbase 1.701 + &nsGkAtoms::lowlimit_, // lowlimit 1.702 + &nsGkAtoms::lt_, // lt 1.703 + &nsGkAtoms::maction_, // maction 1.704 + &nsGkAtoms::maligngroup_, // maligngroup 1.705 + &nsGkAtoms::malignmark_, // malignmark 1.706 + &nsGkAtoms::math, // math 1.707 + &nsGkAtoms::matrix, // matrix 1.708 + &nsGkAtoms::matrixrow_, // matrixrow 1.709 + &nsGkAtoms::max, // max 1.710 + &nsGkAtoms::mean_, // mean 1.711 + &nsGkAtoms::median_, // median 1.712 + &nsGkAtoms::menclose_, // menclose 1.713 + &nsGkAtoms::merror_, // merror 1.714 + &nsGkAtoms::mfenced_, // mfenced 1.715 + &nsGkAtoms::mfrac_, // mfrac 1.716 + &nsGkAtoms::mglyph_, // mglyph 1.717 + &nsGkAtoms::mi_, // mi 1.718 + &nsGkAtoms::min, // min 1.719 + &nsGkAtoms::minus_, // minus 1.720 + &nsGkAtoms::mlabeledtr_, // mlabeledtr 1.721 + &nsGkAtoms::mlongdiv_, // mlongdiv 1.722 + &nsGkAtoms::mmultiscripts_, // mmultiscripts 1.723 + &nsGkAtoms::mn_, // mn 1.724 + &nsGkAtoms::mo_, // mo 1.725 + &nsGkAtoms::mode, // mode 1.726 + &nsGkAtoms::moment_, // moment 1.727 + &nsGkAtoms::momentabout_, // momentabout 1.728 + &nsGkAtoms::mover_, // mover 1.729 + &nsGkAtoms::mpadded_, // mpadded 1.730 + &nsGkAtoms::mphantom_, // mphantom 1.731 + &nsGkAtoms::mprescripts_, // mprescripts 1.732 + &nsGkAtoms::mroot_, // mroot 1.733 + &nsGkAtoms::mrow_, // mrow 1.734 + &nsGkAtoms::ms_, // ms 1.735 + &nsGkAtoms::mscarries_, // mscarries 1.736 + &nsGkAtoms::mscarry_, // mscarry 1.737 + &nsGkAtoms::msgroup_, // msgroup 1.738 + &nsGkAtoms::msline_, // msline 1.739 + &nsGkAtoms::mspace_, // mspace 1.740 + &nsGkAtoms::msqrt_, // msqrt 1.741 + &nsGkAtoms::msrow_, // msrow 1.742 + &nsGkAtoms::mstack_, // mstack 1.743 + &nsGkAtoms::mstyle_, // mstyle 1.744 + &nsGkAtoms::msub_, // msub 1.745 + &nsGkAtoms::msubsup_, // msubsup 1.746 + &nsGkAtoms::msup_, // msup 1.747 + &nsGkAtoms::mtable_, // mtable 1.748 + &nsGkAtoms::mtd_, // mtd 1.749 + &nsGkAtoms::mtext_, // mtext 1.750 + &nsGkAtoms::mtr_, // mtr 1.751 + &nsGkAtoms::munder_, // munder 1.752 + &nsGkAtoms::munderover_, // munderover 1.753 + &nsGkAtoms::naturalnumbers_, // naturalnumbers 1.754 + &nsGkAtoms::neq_, // neq 1.755 + &nsGkAtoms::none, // none 1.756 + &nsGkAtoms::_not, // not 1.757 + &nsGkAtoms::notanumber_, // notanumber 1.758 + &nsGkAtoms::note_, // note 1.759 + &nsGkAtoms::notin_, // notin 1.760 + &nsGkAtoms::notprsubset_, // notprsubset 1.761 + &nsGkAtoms::notsubset_, // notsubset 1.762 + &nsGkAtoms::_or, // or 1.763 + &nsGkAtoms::otherwise, // otherwise 1.764 + &nsGkAtoms::outerproduct_, // outerproduct 1.765 + &nsGkAtoms::partialdiff_, // partialdiff 1.766 + &nsGkAtoms::pi_, // pi 1.767 + &nsGkAtoms::piece_, // piece 1.768 + &nsGkAtoms::piecewise_, // piecewise 1.769 + &nsGkAtoms::plus_, // plus 1.770 + &nsGkAtoms::power_, // power 1.771 + &nsGkAtoms::primes_, // primes 1.772 + &nsGkAtoms::product_, // product 1.773 + &nsGkAtoms::prsubset_, // prsubset 1.774 + &nsGkAtoms::quotient_, // quotient 1.775 + &nsGkAtoms::rationals_, // rationals 1.776 + &nsGkAtoms::real_, // real 1.777 + &nsGkAtoms::reals_, // reals 1.778 + &nsGkAtoms::reln_, // reln 1.779 + &nsGkAtoms::rem, // rem 1.780 + &nsGkAtoms::root_, // root 1.781 + &nsGkAtoms::scalarproduct_, // scalarproduct 1.782 + &nsGkAtoms::sdev_, // sdev 1.783 + &nsGkAtoms::sec_, // sec 1.784 + &nsGkAtoms::sech_, // sech 1.785 + &nsGkAtoms::selector_, // selector 1.786 + &nsGkAtoms::semantics_, // semantics 1.787 + &nsGkAtoms::sep_, // sep 1.788 + &nsGkAtoms::set_, // set 1.789 + &nsGkAtoms::setdiff_, // setdiff 1.790 + &nsGkAtoms::share_, // share 1.791 + &nsGkAtoms::sin_, // sin 1.792 + &nsGkAtoms::sinh_, // sinh 1.793 + &nsGkAtoms::subset_, // subset 1.794 + &nsGkAtoms::sum, // sum 1.795 + &nsGkAtoms::tan_, // tan 1.796 + &nsGkAtoms::tanh_, // tanh 1.797 + &nsGkAtoms::tendsto_, // tendsto 1.798 + &nsGkAtoms::times_, // times 1.799 + &nsGkAtoms::transpose_, // transpose 1.800 + &nsGkAtoms::_true, // true 1.801 + &nsGkAtoms::union_, // union 1.802 + &nsGkAtoms::uplimit_, // uplimit 1.803 + &nsGkAtoms::variance_, // variance 1.804 + &nsGkAtoms::vector_, // vector 1.805 + &nsGkAtoms::vectorproduct_, // vectorproduct 1.806 + &nsGkAtoms::xor_, // xor 1.807 + nullptr 1.808 +}; 1.809 + 1.810 +nsIAtom** const kAttributesMathML[] = { 1.811 + &nsGkAtoms::accent_, // accent 1.812 + &nsGkAtoms::accentunder_, // accentunder 1.813 + &nsGkAtoms::actiontype_, // actiontype 1.814 + &nsGkAtoms::align, // align 1.815 + &nsGkAtoms::alignmentscope_, // alignmentscope 1.816 + &nsGkAtoms::alt, // alt 1.817 + &nsGkAtoms::altimg_, // altimg 1.818 + &nsGkAtoms::altimg_height_, // altimg-height 1.819 + &nsGkAtoms::altimg_valign_, // altimg-valign 1.820 + &nsGkAtoms::altimg_width_, // altimg-width 1.821 + &nsGkAtoms::background, // background 1.822 + &nsGkAtoms::base, // base 1.823 + &nsGkAtoms::bevelled_, // bevelled 1.824 + &nsGkAtoms::cd_, // cd 1.825 + &nsGkAtoms::cdgroup_, // cdgroup 1.826 + &nsGkAtoms::charalign_, // charalign 1.827 + &nsGkAtoms::close, // close 1.828 + &nsGkAtoms::closure_, // closure 1.829 + &nsGkAtoms::color, // color 1.830 + &nsGkAtoms::columnalign_, // columnalign 1.831 + &nsGkAtoms::columnalignment_, // columnalignment 1.832 + &nsGkAtoms::columnlines_, // columnlines 1.833 + &nsGkAtoms::columnspacing_, // columnspacing 1.834 + &nsGkAtoms::columnspan_, // columnspan 1.835 + &nsGkAtoms::columnwidth_, // columnwidth 1.836 + &nsGkAtoms::crossout_, // crossout 1.837 + &nsGkAtoms::decimalpoint_, // decimalpoint 1.838 + &nsGkAtoms::definitionURL_, // definitionURL 1.839 + &nsGkAtoms::denomalign_, // denomalign 1.840 + &nsGkAtoms::depth_, // depth 1.841 + &nsGkAtoms::dir, // dir 1.842 + &nsGkAtoms::display, // display 1.843 + &nsGkAtoms::displaystyle_, // displaystyle 1.844 + &nsGkAtoms::edge_, // edge 1.845 + &nsGkAtoms::encoding, // encoding 1.846 + &nsGkAtoms::equalcolumns_, // equalcolumns 1.847 + &nsGkAtoms::equalrows_, // equalrows 1.848 + &nsGkAtoms::fence_, // fence 1.849 + &nsGkAtoms::fontfamily_, // fontfamily 1.850 + &nsGkAtoms::fontsize_, // fontsize 1.851 + &nsGkAtoms::fontstyle_, // fontstyle 1.852 + &nsGkAtoms::fontweight_, // fontweight 1.853 + &nsGkAtoms::form, // form 1.854 + &nsGkAtoms::frame, // frame 1.855 + &nsGkAtoms::framespacing_, // framespacing 1.856 + &nsGkAtoms::groupalign_, // groupalign 1.857 + &nsGkAtoms::height, // height 1.858 + &nsGkAtoms::href, // href 1.859 + &nsGkAtoms::id, // id 1.860 + &nsGkAtoms::indentalign_, // indentalign 1.861 + &nsGkAtoms::indentalignfirst_, // indentalignfirst 1.862 + &nsGkAtoms::indentalignlast_, // indentalignlast 1.863 + &nsGkAtoms::indentshift_, // indentshift 1.864 + &nsGkAtoms::indentshiftfirst_, // indentshiftfirst 1.865 + &nsGkAtoms::indenttarget_, // indenttarget 1.866 + &nsGkAtoms::index, // index 1.867 + &nsGkAtoms::integer, // integer 1.868 + &nsGkAtoms::largeop_, // largeop 1.869 + &nsGkAtoms::length, // length 1.870 + &nsGkAtoms::linebreak_, // linebreak 1.871 + &nsGkAtoms::linebreakmultchar_, // linebreakmultchar 1.872 + &nsGkAtoms::linebreakstyle_, // linebreakstyle 1.873 + &nsGkAtoms::linethickness_, // linethickness 1.874 + &nsGkAtoms::location_, // location 1.875 + &nsGkAtoms::longdivstyle_, // longdivstyle 1.876 + &nsGkAtoms::lquote_, // lquote 1.877 + &nsGkAtoms::lspace_, // lspace 1.878 + &nsGkAtoms::ltr, // ltr 1.879 + &nsGkAtoms::mathbackground_, // mathbackground 1.880 + &nsGkAtoms::mathcolor_, // mathcolor 1.881 + &nsGkAtoms::mathsize_, // mathsize 1.882 + &nsGkAtoms::mathvariant_, // mathvariant 1.883 + &nsGkAtoms::maxsize_, // maxsize 1.884 + &nsGkAtoms::minlabelspacing_, // minlabelspacing 1.885 + &nsGkAtoms::minsize_, // minsize 1.886 + &nsGkAtoms::movablelimits_, // movablelimits 1.887 + &nsGkAtoms::msgroup_, // msgroup 1.888 + &nsGkAtoms::name, // name 1.889 + &nsGkAtoms::newline, // newline 1.890 + &nsGkAtoms::notation_, // notation 1.891 + &nsGkAtoms::numalign_, // numalign 1.892 + &nsGkAtoms::number, // number 1.893 + &nsGkAtoms::open, // open 1.894 + &nsGkAtoms::order, // order 1.895 + &nsGkAtoms::other_, // other 1.896 + &nsGkAtoms::overflow, // overflow 1.897 + &nsGkAtoms::position, // position 1.898 + &nsGkAtoms::role, // role 1.899 + &nsGkAtoms::rowalign_, // rowalign 1.900 + &nsGkAtoms::rowlines_, // rowlines 1.901 + &nsGkAtoms::rowspacing_, // rowspacing 1.902 + &nsGkAtoms::rowspan, // rowspan 1.903 + &nsGkAtoms::rquote_, // rquote 1.904 + &nsGkAtoms::rspace_, // rspace 1.905 + &nsGkAtoms::schemaLocation_, // schemaLocation 1.906 + &nsGkAtoms::scriptlevel_, // scriptlevel 1.907 + &nsGkAtoms::scriptminsize_, // scriptminsize 1.908 + &nsGkAtoms::scriptsize_, // scriptsize 1.909 + &nsGkAtoms::scriptsizemultiplier_, // scriptsizemultiplier 1.910 + &nsGkAtoms::selection_, // selection 1.911 + &nsGkAtoms::separator_, // separator 1.912 + &nsGkAtoms::separators_, // separators 1.913 + &nsGkAtoms::shift_, // shift 1.914 + &nsGkAtoms::side_, // side 1.915 + &nsGkAtoms::src, // src 1.916 + &nsGkAtoms::stackalign_, // stackalign 1.917 + &nsGkAtoms::stretchy_, // stretchy 1.918 + &nsGkAtoms::subscriptshift_, // subscriptshift 1.919 + &nsGkAtoms::superscriptshift_, // superscriptshift 1.920 + &nsGkAtoms::symmetric_, // symmetric 1.921 + &nsGkAtoms::type, // type 1.922 + &nsGkAtoms::voffset_, // voffset 1.923 + &nsGkAtoms::width, // width 1.924 + &nsGkAtoms::xref_, // xref 1.925 + nullptr 1.926 +}; 1.927 + 1.928 +nsIAtom** const kURLAttributesMathML[] = { 1.929 + &nsGkAtoms::href, 1.930 + &nsGkAtoms::src, 1.931 + &nsGkAtoms::cdgroup_, 1.932 + &nsGkAtoms::altimg_, 1.933 + &nsGkAtoms::definitionURL_, 1.934 + nullptr 1.935 +}; 1.936 + 1.937 +nsTHashtable<nsISupportsHashKey>* nsTreeSanitizer::sElementsHTML = nullptr; 1.938 +nsTHashtable<nsISupportsHashKey>* nsTreeSanitizer::sAttributesHTML = nullptr; 1.939 +nsTHashtable<nsISupportsHashKey>* nsTreeSanitizer::sPresAttributesHTML = nullptr; 1.940 +nsTHashtable<nsISupportsHashKey>* nsTreeSanitizer::sElementsSVG = nullptr; 1.941 +nsTHashtable<nsISupportsHashKey>* nsTreeSanitizer::sAttributesSVG = nullptr; 1.942 +nsTHashtable<nsISupportsHashKey>* nsTreeSanitizer::sElementsMathML = nullptr; 1.943 +nsTHashtable<nsISupportsHashKey>* nsTreeSanitizer::sAttributesMathML = nullptr; 1.944 +nsIPrincipal* nsTreeSanitizer::sNullPrincipal = nullptr; 1.945 + 1.946 +nsTreeSanitizer::nsTreeSanitizer(uint32_t aFlags) 1.947 + : mAllowStyles(aFlags & nsIParserUtils::SanitizerAllowStyle) 1.948 + , mAllowComments(aFlags & nsIParserUtils::SanitizerAllowComments) 1.949 + , mDropNonCSSPresentation(aFlags & 1.950 + nsIParserUtils::SanitizerDropNonCSSPresentation) 1.951 + , mDropForms(aFlags & nsIParserUtils::SanitizerDropForms) 1.952 + , mCidEmbedsOnly(aFlags & 1.953 + nsIParserUtils::SanitizerCidEmbedsOnly) 1.954 + , mDropMedia(aFlags & nsIParserUtils::SanitizerDropMedia) 1.955 + , mFullDocument(false) 1.956 +{ 1.957 + if (mCidEmbedsOnly) { 1.958 + // Sanitizing styles for external references is not supported. 1.959 + mAllowStyles = false; 1.960 + } 1.961 + if (!sElementsHTML) { 1.962 + // Initialize lazily to avoid having to initialize at all if the user 1.963 + // doesn't paste HTML or load feeds. 1.964 + InitializeStatics(); 1.965 + } 1.966 +} 1.967 + 1.968 +bool 1.969 +nsTreeSanitizer::MustFlatten(int32_t aNamespace, nsIAtom* aLocal) 1.970 +{ 1.971 + if (aNamespace == kNameSpaceID_XHTML) { 1.972 + if (mDropNonCSSPresentation && (nsGkAtoms::font == aLocal || 1.973 + nsGkAtoms::center == aLocal)) { 1.974 + return true; 1.975 + } 1.976 + if (mDropForms && (nsGkAtoms::form == aLocal || 1.977 + nsGkAtoms::input == aLocal || 1.978 + nsGkAtoms::keygen == aLocal || 1.979 + nsGkAtoms::option == aLocal || 1.980 + nsGkAtoms::optgroup == aLocal)) { 1.981 + return true; 1.982 + } 1.983 + if (mFullDocument && (nsGkAtoms::title == aLocal || 1.984 + nsGkAtoms::html == aLocal || 1.985 + nsGkAtoms::head == aLocal || 1.986 + nsGkAtoms::body == aLocal)) { 1.987 + return false; 1.988 + } 1.989 + return !sElementsHTML->GetEntry(aLocal); 1.990 + } 1.991 + if (aNamespace == kNameSpaceID_SVG) { 1.992 + if (mCidEmbedsOnly || mDropMedia) { 1.993 + // Sanitizing CSS-based URL references inside SVG presentational 1.994 + // attributes is not supported, so flattening for cid: embed case. 1.995 + return true; 1.996 + } 1.997 + return !sElementsSVG->GetEntry(aLocal); 1.998 + } 1.999 + if (aNamespace == kNameSpaceID_MathML) { 1.1000 + return !sElementsMathML->GetEntry(aLocal); 1.1001 + } 1.1002 + return true; 1.1003 +} 1.1004 + 1.1005 +bool 1.1006 +nsTreeSanitizer::IsURL(nsIAtom*** aURLs, nsIAtom* aLocalName) 1.1007 +{ 1.1008 + nsIAtom** atomPtrPtr; 1.1009 + while ((atomPtrPtr = *aURLs)) { 1.1010 + if (*atomPtrPtr == aLocalName) { 1.1011 + return true; 1.1012 + } 1.1013 + ++aURLs; 1.1014 + } 1.1015 + return false; 1.1016 +} 1.1017 + 1.1018 +bool 1.1019 +nsTreeSanitizer::MustPrune(int32_t aNamespace, 1.1020 + nsIAtom* aLocal, 1.1021 + mozilla::dom::Element* aElement) 1.1022 +{ 1.1023 + // To avoid attacks where a MathML script becomes something that gets 1.1024 + // serialized in a way that it parses back as an HTML script, let's just 1.1025 + // drop elements with the local name 'script' regardless of namespace. 1.1026 + if (nsGkAtoms::script == aLocal) { 1.1027 + return true; 1.1028 + } 1.1029 + if (aNamespace == kNameSpaceID_XHTML) { 1.1030 + if (nsGkAtoms::title == aLocal && !mFullDocument) { 1.1031 + // emulate the quirks of the old parser 1.1032 + return true; 1.1033 + } 1.1034 + if (mDropForms && (nsGkAtoms::select == aLocal || 1.1035 + nsGkAtoms::button == aLocal || 1.1036 + nsGkAtoms::datalist == aLocal)) { 1.1037 + return true; 1.1038 + } 1.1039 + if (mDropMedia && (nsGkAtoms::img == aLocal || 1.1040 + nsGkAtoms::video == aLocal || 1.1041 + nsGkAtoms::audio == aLocal || 1.1042 + nsGkAtoms::source == aLocal)) { 1.1043 + return true; 1.1044 + } 1.1045 + if (nsGkAtoms::meta == aLocal && 1.1046 + (aElement->HasAttr(kNameSpaceID_None, nsGkAtoms::charset) || 1.1047 + aElement->HasAttr(kNameSpaceID_None, nsGkAtoms::httpEquiv))) { 1.1048 + // Throw away charset declarations even if they also have microdata 1.1049 + // which they can't validly have. 1.1050 + return true; 1.1051 + } 1.1052 + if (((!mFullDocument && nsGkAtoms::meta == aLocal) || 1.1053 + nsGkAtoms::link == aLocal) && 1.1054 + !(aElement->HasAttr(kNameSpaceID_None, nsGkAtoms::itemprop) || 1.1055 + aElement->HasAttr(kNameSpaceID_None, nsGkAtoms::itemscope))) { 1.1056 + // emulate old behavior for non-Microdata <meta> and <link> presumably 1.1057 + // in <head>. <meta> and <link> are whitelisted in order to avoid 1.1058 + // corrupting Microdata when they appear in <body>. Note that 1.1059 + // SanitizeAttributes() will remove the rel attribute from <link> and 1.1060 + // the name attribute from <meta>. 1.1061 + return true; 1.1062 + } 1.1063 + } 1.1064 + if (mAllowStyles) { 1.1065 + if (nsGkAtoms::style == aLocal && !(aNamespace == kNameSpaceID_XHTML 1.1066 + || aNamespace == kNameSpaceID_SVG)) { 1.1067 + return true; 1.1068 + } 1.1069 + return false; 1.1070 + } 1.1071 + if (nsGkAtoms::style == aLocal) { 1.1072 + return true; 1.1073 + } 1.1074 + return false; 1.1075 +} 1.1076 + 1.1077 +bool 1.1078 +nsTreeSanitizer::SanitizeStyleRule(mozilla::css::StyleRule *aRule, 1.1079 + nsAutoString &aRuleText) 1.1080 +{ 1.1081 + bool didSanitize = false; 1.1082 + aRuleText.Truncate(); 1.1083 + mozilla::css::Declaration* style = aRule->GetDeclaration(); 1.1084 + if (style) { 1.1085 + didSanitize = style->HasProperty(eCSSProperty_binding); 1.1086 + style->RemoveProperty(eCSSProperty_binding); 1.1087 + style->ToString(aRuleText); 1.1088 + } 1.1089 + return didSanitize; 1.1090 +} 1.1091 + 1.1092 +bool 1.1093 +nsTreeSanitizer::SanitizeStyleSheet(const nsAString& aOriginal, 1.1094 + nsAString& aSanitized, 1.1095 + nsIDocument* aDocument, 1.1096 + nsIURI* aBaseURI) 1.1097 +{ 1.1098 + nsresult rv; 1.1099 + aSanitized.Truncate(); 1.1100 + // aSanitized will hold the permitted CSS text. 1.1101 + // -moz-binding is blacklisted. 1.1102 + bool didSanitize = false; 1.1103 + // Create a sheet to hold the parsed CSS 1.1104 + nsRefPtr<nsCSSStyleSheet> sheet = new nsCSSStyleSheet(CORS_NONE); 1.1105 + sheet->SetURIs(aDocument->GetDocumentURI(), nullptr, aBaseURI); 1.1106 + sheet->SetPrincipal(aDocument->NodePrincipal()); 1.1107 + // Create the CSS parser, and parse the CSS text. 1.1108 + nsCSSParser parser(nullptr, sheet); 1.1109 + rv = parser.ParseSheet(aOriginal, aDocument->GetDocumentURI(), aBaseURI, 1.1110 + aDocument->NodePrincipal(), 0, false); 1.1111 + NS_ENSURE_SUCCESS(rv, true); 1.1112 + // Mark the sheet as complete. 1.1113 + NS_ABORT_IF_FALSE(!sheet->IsModified(), 1.1114 + "should not get marked modified during parsing"); 1.1115 + sheet->SetComplete(); 1.1116 + // Loop through all the rules found in the CSS text 1.1117 + int32_t ruleCount = sheet->StyleRuleCount(); 1.1118 + for (int32_t i = 0; i < ruleCount; ++i) { 1.1119 + mozilla::css::Rule* rule = sheet->GetStyleRuleAt(i); 1.1120 + if (!rule) 1.1121 + continue; 1.1122 + switch (rule->GetType()) { 1.1123 + default: 1.1124 + didSanitize = true; 1.1125 + // Ignore these rule types. 1.1126 + break; 1.1127 + case mozilla::css::Rule::NAMESPACE_RULE: 1.1128 + case mozilla::css::Rule::FONT_FACE_RULE: { 1.1129 + // Append @namespace and @font-face rules verbatim. 1.1130 + nsAutoString cssText; 1.1131 + nsCOMPtr<nsIDOMCSSRule> styleRule = do_QueryInterface(rule); 1.1132 + if (styleRule) { 1.1133 + rv = styleRule->GetCssText(cssText); 1.1134 + if (NS_SUCCEEDED(rv)) { 1.1135 + aSanitized.Append(cssText); 1.1136 + } 1.1137 + } 1.1138 + break; 1.1139 + } 1.1140 + case mozilla::css::Rule::STYLE_RULE: { 1.1141 + // For style rules, we will just look for and remove the 1.1142 + // -moz-binding properties. 1.1143 + nsRefPtr<mozilla::css::StyleRule> styleRule = do_QueryObject(rule); 1.1144 + NS_ASSERTION(styleRule, "Must be a style rule"); 1.1145 + nsAutoString decl; 1.1146 + bool sanitized = SanitizeStyleRule(styleRule, decl); 1.1147 + didSanitize = sanitized || didSanitize; 1.1148 + if (!sanitized) { 1.1149 + styleRule->GetCssText(decl); 1.1150 + } 1.1151 + aSanitized.Append(decl); 1.1152 + } 1.1153 + } 1.1154 + } 1.1155 + return didSanitize; 1.1156 +} 1.1157 + 1.1158 +void 1.1159 +nsTreeSanitizer::SanitizeAttributes(mozilla::dom::Element* aElement, 1.1160 + nsTHashtable<nsISupportsHashKey>* aAllowed, 1.1161 + nsIAtom*** aURLs, 1.1162 + bool aAllowXLink, 1.1163 + bool aAllowStyle, 1.1164 + bool aAllowDangerousSrc) 1.1165 +{ 1.1166 + uint32_t ac = aElement->GetAttrCount(); 1.1167 + 1.1168 + nsresult rv; 1.1169 + 1.1170 + for (int32_t i = ac - 1; i >= 0; --i) { 1.1171 + rv = NS_OK; 1.1172 + const nsAttrName* attrName = aElement->GetAttrNameAt(i); 1.1173 + int32_t attrNs = attrName->NamespaceID(); 1.1174 + nsCOMPtr<nsIAtom> attrLocal = attrName->LocalName(); 1.1175 + 1.1176 + if (kNameSpaceID_None == attrNs) { 1.1177 + if (aAllowStyle && nsGkAtoms::style == attrLocal) { 1.1178 + nsCOMPtr<nsIURI> baseURI = aElement->GetBaseURI(); 1.1179 + nsIDocument* document = aElement->OwnerDoc(); 1.1180 + // Pass the CSS Loader object to the parser, to allow parser error 1.1181 + // reports to include the outer window ID. 1.1182 + nsCSSParser parser(document->CSSLoader()); 1.1183 + nsRefPtr<mozilla::css::StyleRule> rule; 1.1184 + nsAutoString value; 1.1185 + aElement->GetAttr(attrNs, attrLocal, value); 1.1186 + rv = parser.ParseStyleAttribute(value, 1.1187 + document->GetDocumentURI(), 1.1188 + baseURI, 1.1189 + document->NodePrincipal(), 1.1190 + getter_AddRefs(rule)); 1.1191 + if (NS_SUCCEEDED(rv)) { 1.1192 + nsAutoString cleanValue; 1.1193 + if (SanitizeStyleRule(rule, cleanValue)) { 1.1194 + aElement->SetAttr(kNameSpaceID_None, 1.1195 + nsGkAtoms::style, 1.1196 + cleanValue, 1.1197 + false); 1.1198 + } 1.1199 + } 1.1200 + continue; 1.1201 + } 1.1202 + if (aAllowDangerousSrc && nsGkAtoms::src == attrLocal) { 1.1203 + continue; 1.1204 + } 1.1205 + if (IsURL(aURLs, attrLocal)) { 1.1206 + if (SanitizeURL(aElement, attrNs, attrLocal)) { 1.1207 + // in case the attribute removal shuffled the attribute order, start 1.1208 + // the loop again. 1.1209 + --ac; 1.1210 + i = ac; // i will be decremented immediately thanks to the for loop 1.1211 + continue; 1.1212 + } 1.1213 + // else fall through to see if there's another reason to drop this 1.1214 + // attribute (in particular if the attribute is background="" on an 1.1215 + // HTML element) 1.1216 + } 1.1217 + if (!mDropNonCSSPresentation && 1.1218 + (aAllowed == sAttributesHTML) && // element is HTML 1.1219 + sPresAttributesHTML->GetEntry(attrLocal)) { 1.1220 + continue; 1.1221 + } 1.1222 + if (aAllowed->GetEntry(attrLocal) && 1.1223 + !((attrLocal == nsGkAtoms::rel && 1.1224 + aElement->IsHTML(nsGkAtoms::link)) || 1.1225 + (!mFullDocument && 1.1226 + attrLocal == nsGkAtoms::name && 1.1227 + aElement->IsHTML(nsGkAtoms::meta)))) { 1.1228 + // name="" and rel="" are whitelisted, but treat them as blacklisted 1.1229 + // for <meta name> (fragment case) and <link rel> (all cases) to avoid 1.1230 + // document-wide metadata or styling overrides with non-conforming 1.1231 + // <meta name itemprop> or 1.1232 + // <link rel itemprop> 1.1233 + continue; 1.1234 + } 1.1235 + const char16_t* localStr = attrLocal->GetUTF16String(); 1.1236 + // Allow underscore to cater to the MCE editor library. 1.1237 + // Allow data-* on SVG and MathML, too, as a forward-compat measure. 1.1238 + if (*localStr == '_' || (attrLocal->GetLength() > 5 && localStr[0] == 'd' 1.1239 + && localStr[1] == 'a' && localStr[2] == 't' && localStr[3] == 'a' 1.1240 + && localStr[4] == '-')) { 1.1241 + continue; 1.1242 + } 1.1243 + // else not allowed 1.1244 + } else if (kNameSpaceID_XML == attrNs) { 1.1245 + if (nsGkAtoms::base == attrLocal) { 1.1246 + if (SanitizeURL(aElement, attrNs, attrLocal)) { 1.1247 + // in case the attribute removal shuffled the attribute order, start 1.1248 + // the loop again. 1.1249 + --ac; 1.1250 + i = ac; // i will be decremented immediately thanks to the for loop 1.1251 + } 1.1252 + continue; 1.1253 + } 1.1254 + if (nsGkAtoms::lang == attrLocal || nsGkAtoms::space == attrLocal) { 1.1255 + continue; 1.1256 + } 1.1257 + // else not allowed 1.1258 + } else if (aAllowXLink && kNameSpaceID_XLink == attrNs) { 1.1259 + if (nsGkAtoms::href == attrLocal) { 1.1260 + if (SanitizeURL(aElement, attrNs, attrLocal)) { 1.1261 + // in case the attribute removal shuffled the attribute order, start 1.1262 + // the loop again. 1.1263 + --ac; 1.1264 + i = ac; // i will be decremented immediately thanks to the for loop 1.1265 + } 1.1266 + continue; 1.1267 + } 1.1268 + if (nsGkAtoms::type == attrLocal || nsGkAtoms::title == attrLocal 1.1269 + || nsGkAtoms::show == attrLocal || nsGkAtoms::actuate == attrLocal) { 1.1270 + continue; 1.1271 + } 1.1272 + // else not allowed 1.1273 + } 1.1274 + aElement->UnsetAttr(kNameSpaceID_None, attrLocal, false); 1.1275 + // in case the attribute removal shuffled the attribute order, start the 1.1276 + // loop again. 1.1277 + --ac; 1.1278 + i = ac; // i will be decremented immediately thanks to the for loop 1.1279 + } 1.1280 + 1.1281 + // If we've got HTML audio or video, add the controls attribute, because 1.1282 + // otherwise the content is unplayable with scripts removed. 1.1283 + if (aElement->IsHTML(nsGkAtoms::video) || 1.1284 + aElement->IsHTML(nsGkAtoms::audio)) { 1.1285 + aElement->SetAttr(kNameSpaceID_None, 1.1286 + nsGkAtoms::controls, 1.1287 + EmptyString(), 1.1288 + false); 1.1289 + } 1.1290 +} 1.1291 + 1.1292 +bool 1.1293 +nsTreeSanitizer::SanitizeURL(mozilla::dom::Element* aElement, 1.1294 + int32_t aNamespace, 1.1295 + nsIAtom* aLocalName) 1.1296 +{ 1.1297 + nsAutoString value; 1.1298 + aElement->GetAttr(aNamespace, aLocalName, value); 1.1299 + 1.1300 + // Get value and remove mandatory quotes 1.1301 + static const char* kWhitespace = "\n\r\t\b"; 1.1302 + const nsAString& v = 1.1303 + nsContentUtils::TrimCharsInSet(kWhitespace, value); 1.1304 + 1.1305 + nsIScriptSecurityManager* secMan = nsContentUtils::GetSecurityManager(); 1.1306 + uint32_t flags = nsIScriptSecurityManager::DISALLOW_INHERIT_PRINCIPAL; 1.1307 + 1.1308 + nsCOMPtr<nsIURI> baseURI = aElement->GetBaseURI(); 1.1309 + nsCOMPtr<nsIURI> attrURI; 1.1310 + nsresult rv = NS_NewURI(getter_AddRefs(attrURI), v, nullptr, baseURI); 1.1311 + if (NS_SUCCEEDED(rv)) { 1.1312 + if (mCidEmbedsOnly && 1.1313 + kNameSpaceID_None == aNamespace) { 1.1314 + if (nsGkAtoms::src == aLocalName || nsGkAtoms::background == aLocalName) { 1.1315 + // comm-central uses a hack that makes nsIURIs created with cid: specs 1.1316 + // actually have an about:blank spec. Therefore, nsIURI facilities are 1.1317 + // useless for cid: when comm-central code is participating. 1.1318 + if (!(v.Length() > 4 && 1.1319 + (v[0] == 'c' || v[0] == 'C') && 1.1320 + (v[1] == 'i' || v[1] == 'I') && 1.1321 + (v[2] == 'd' || v[2] == 'D') && 1.1322 + v[3] == ':')) { 1.1323 + rv = NS_ERROR_FAILURE; 1.1324 + } 1.1325 + } else if (nsGkAtoms::cdgroup_ == aLocalName || 1.1326 + nsGkAtoms::altimg_ == aLocalName || 1.1327 + nsGkAtoms::definitionURL_ == aLocalName) { 1.1328 + // Gecko doesn't fetch these now and shouldn't in the future, but 1.1329 + // in case someone goofs with these in the future, let's drop them. 1.1330 + rv = NS_ERROR_FAILURE; 1.1331 + } else { 1.1332 + rv = secMan->CheckLoadURIWithPrincipal(sNullPrincipal, attrURI, flags); 1.1333 + } 1.1334 + } else { 1.1335 + rv = secMan->CheckLoadURIWithPrincipal(sNullPrincipal, attrURI, flags); 1.1336 + } 1.1337 + } 1.1338 + if (NS_FAILED(rv)) { 1.1339 + aElement->UnsetAttr(aNamespace, aLocalName, false); 1.1340 + return true; 1.1341 + } 1.1342 + return false; 1.1343 +} 1.1344 + 1.1345 +void 1.1346 +nsTreeSanitizer::Sanitize(nsIContent* aFragment) 1.1347 +{ 1.1348 + // If you want to relax these preconditions, be sure to check the code in 1.1349 + // here that notifies / does not notify or that fires mutation events if 1.1350 + // in tree. 1.1351 + NS_PRECONDITION(aFragment->IsNodeOfType(nsINode::eDOCUMENT_FRAGMENT), 1.1352 + "Argument was not DOM fragment."); 1.1353 + NS_PRECONDITION(!aFragment->IsInDoc(), "The fragment is in doc?"); 1.1354 + 1.1355 + mFullDocument = false; 1.1356 + SanitizeChildren(aFragment); 1.1357 +} 1.1358 + 1.1359 +void 1.1360 +nsTreeSanitizer::Sanitize(nsIDocument* aDocument) 1.1361 +{ 1.1362 + // If you want to relax these preconditions, be sure to check the code in 1.1363 + // here that notifies / does not notify or that fires mutation events if 1.1364 + // in tree. 1.1365 +#ifdef DEBUG 1.1366 + NS_PRECONDITION(!aDocument->GetContainer(), "The document is in a shell."); 1.1367 + nsRefPtr<mozilla::dom::Element> root = aDocument->GetRootElement(); 1.1368 + NS_PRECONDITION(root->IsHTML(nsGkAtoms::html), "Not HTML root."); 1.1369 +#endif 1.1370 + 1.1371 + mFullDocument = true; 1.1372 + SanitizeChildren(aDocument); 1.1373 +} 1.1374 + 1.1375 +void 1.1376 +nsTreeSanitizer::SanitizeChildren(nsINode* aRoot) 1.1377 +{ 1.1378 + nsIContent* node = aRoot->GetFirstChild(); 1.1379 + while (node) { 1.1380 + if (node->IsElement()) { 1.1381 + mozilla::dom::Element* elt = node->AsElement(); 1.1382 + nsINodeInfo* nodeInfo = node->NodeInfo(); 1.1383 + nsIAtom* localName = nodeInfo->NameAtom(); 1.1384 + int32_t ns = nodeInfo->NamespaceID(); 1.1385 + 1.1386 + if (MustPrune(ns, localName, elt)) { 1.1387 + RemoveAllAttributes(node); 1.1388 + nsIContent* descendant = node; 1.1389 + while ((descendant = descendant->GetNextNode(node))) { 1.1390 + RemoveAllAttributes(descendant); 1.1391 + } 1.1392 + nsIContent* next = node->GetNextNonChildNode(aRoot); 1.1393 + node->RemoveFromParent(); 1.1394 + node = next; 1.1395 + continue; 1.1396 + } 1.1397 + if (nsGkAtoms::style == localName) { 1.1398 + // If styles aren't allowed, style elements got pruned above. Even 1.1399 + // if styles are allowed, non-HTML, non-SVG style elements got pruned 1.1400 + // above. 1.1401 + NS_ASSERTION(ns == kNameSpaceID_XHTML || ns == kNameSpaceID_SVG, 1.1402 + "Should have only HTML or SVG here!"); 1.1403 + nsAutoString styleText; 1.1404 + if (!nsContentUtils::GetNodeTextContent(node, false, styleText)) { 1.1405 + NS_RUNTIMEABORT("OOM"); 1.1406 + } 1.1407 + nsAutoString sanitizedStyle; 1.1408 + nsCOMPtr<nsIURI> baseURI = node->GetBaseURI(); 1.1409 + if (SanitizeStyleSheet(styleText, 1.1410 + sanitizedStyle, 1.1411 + aRoot->OwnerDoc(), 1.1412 + baseURI)) { 1.1413 + nsContentUtils::SetNodeTextContent(node, sanitizedStyle, true); 1.1414 + } else { 1.1415 + // If the node had non-text child nodes, this operation zaps those. 1.1416 + nsContentUtils::SetNodeTextContent(node, styleText, true); 1.1417 + } 1.1418 + if (ns == kNameSpaceID_XHTML) { 1.1419 + SanitizeAttributes(elt, 1.1420 + sAttributesHTML, 1.1421 + (nsIAtom***)kURLAttributesHTML, 1.1422 + false, 1.1423 + mAllowStyles, 1.1424 + false); 1.1425 + } else { 1.1426 + SanitizeAttributes(elt, 1.1427 + sAttributesSVG, 1.1428 + (nsIAtom***)kURLAttributesSVG, 1.1429 + true, 1.1430 + mAllowStyles, 1.1431 + false); 1.1432 + } 1.1433 + node = node->GetNextNonChildNode(aRoot); 1.1434 + continue; 1.1435 + } 1.1436 + if (MustFlatten(ns, localName)) { 1.1437 + RemoveAllAttributes(node); 1.1438 + nsIContent* next = node->GetNextNode(aRoot); 1.1439 + nsIContent* parent = node->GetParent(); 1.1440 + nsCOMPtr<nsIContent> child; // Must keep the child alive during move 1.1441 + ErrorResult rv; 1.1442 + while ((child = node->GetFirstChild())) { 1.1443 + parent->InsertBefore(*child, node, rv); 1.1444 + if (rv.Failed()) { 1.1445 + break; 1.1446 + } 1.1447 + } 1.1448 + node->RemoveFromParent(); 1.1449 + node = next; 1.1450 + continue; 1.1451 + } 1.1452 + NS_ASSERTION(ns == kNameSpaceID_XHTML || 1.1453 + ns == kNameSpaceID_SVG || 1.1454 + ns == kNameSpaceID_MathML, 1.1455 + "Should have only HTML, MathML or SVG here!"); 1.1456 + if (ns == kNameSpaceID_XHTML) { 1.1457 + SanitizeAttributes(elt, 1.1458 + sAttributesHTML, 1.1459 + (nsIAtom***)kURLAttributesHTML, 1.1460 + false, mAllowStyles, 1.1461 + (nsGkAtoms::img == localName) && 1.1462 + !mCidEmbedsOnly); 1.1463 + } else if (ns == kNameSpaceID_SVG) { 1.1464 + SanitizeAttributes(elt, 1.1465 + sAttributesSVG, 1.1466 + (nsIAtom***)kURLAttributesSVG, 1.1467 + true, 1.1468 + mAllowStyles, 1.1469 + false); 1.1470 + } else { 1.1471 + SanitizeAttributes(elt, 1.1472 + sAttributesMathML, 1.1473 + (nsIAtom***)kURLAttributesMathML, 1.1474 + true, 1.1475 + false, 1.1476 + false); 1.1477 + } 1.1478 + node = node->GetNextNode(aRoot); 1.1479 + continue; 1.1480 + } 1.1481 + NS_ASSERTION(!node->GetFirstChild(), "How come non-element node had kids?"); 1.1482 + nsIContent* next = node->GetNextNonChildNode(aRoot); 1.1483 + if (!mAllowComments && node->IsNodeOfType(nsINode::eCOMMENT)) { 1.1484 + node->RemoveFromParent(); 1.1485 + } 1.1486 + node = next; 1.1487 + } 1.1488 +} 1.1489 + 1.1490 +void 1.1491 +nsTreeSanitizer::RemoveAllAttributes(nsIContent* aElement) 1.1492 +{ 1.1493 + const nsAttrName* attrName; 1.1494 + while ((attrName = aElement->GetAttrNameAt(0))) { 1.1495 + int32_t attrNs = attrName->NamespaceID(); 1.1496 + nsCOMPtr<nsIAtom> attrLocal = attrName->LocalName(); 1.1497 + aElement->UnsetAttr(attrNs, attrLocal, false); 1.1498 + } 1.1499 +} 1.1500 + 1.1501 +void 1.1502 +nsTreeSanitizer::InitializeStatics() 1.1503 +{ 1.1504 + NS_PRECONDITION(!sElementsHTML, "Initializing a second time."); 1.1505 + 1.1506 + sElementsHTML = new nsTHashtable<nsISupportsHashKey>(ArrayLength(kElementsHTML)); 1.1507 + for (uint32_t i = 0; kElementsHTML[i]; i++) { 1.1508 + sElementsHTML->PutEntry(*kElementsHTML[i]); 1.1509 + } 1.1510 + 1.1511 + sAttributesHTML = new nsTHashtable<nsISupportsHashKey>(ArrayLength(kAttributesHTML)); 1.1512 + for (uint32_t i = 0; kAttributesHTML[i]; i++) { 1.1513 + sAttributesHTML->PutEntry(*kAttributesHTML[i]); 1.1514 + } 1.1515 + 1.1516 + sPresAttributesHTML = new nsTHashtable<nsISupportsHashKey>(ArrayLength(kPresAttributesHTML)); 1.1517 + for (uint32_t i = 0; kPresAttributesHTML[i]; i++) { 1.1518 + sPresAttributesHTML->PutEntry(*kPresAttributesHTML[i]); 1.1519 + } 1.1520 + 1.1521 + sElementsSVG = new nsTHashtable<nsISupportsHashKey>(ArrayLength(kElementsSVG)); 1.1522 + for (uint32_t i = 0; kElementsSVG[i]; i++) { 1.1523 + sElementsSVG->PutEntry(*kElementsSVG[i]); 1.1524 + } 1.1525 + 1.1526 + sAttributesSVG = new nsTHashtable<nsISupportsHashKey>(ArrayLength(kAttributesSVG)); 1.1527 + for (uint32_t i = 0; kAttributesSVG[i]; i++) { 1.1528 + sAttributesSVG->PutEntry(*kAttributesSVG[i]); 1.1529 + } 1.1530 + 1.1531 + sElementsMathML = new nsTHashtable<nsISupportsHashKey>(ArrayLength(kElementsMathML)); 1.1532 + for (uint32_t i = 0; kElementsMathML[i]; i++) { 1.1533 + sElementsMathML->PutEntry(*kElementsMathML[i]); 1.1534 + } 1.1535 + 1.1536 + sAttributesMathML = new nsTHashtable<nsISupportsHashKey>(ArrayLength(kAttributesMathML)); 1.1537 + for (uint32_t i = 0; kAttributesMathML[i]; i++) { 1.1538 + sAttributesMathML->PutEntry(*kAttributesMathML[i]); 1.1539 + } 1.1540 + 1.1541 + nsCOMPtr<nsIPrincipal> principal = 1.1542 + do_CreateInstance(NS_NULLPRINCIPAL_CONTRACTID); 1.1543 + principal.forget(&sNullPrincipal); 1.1544 +} 1.1545 + 1.1546 +void 1.1547 +nsTreeSanitizer::ReleaseStatics() 1.1548 +{ 1.1549 + delete sElementsHTML; 1.1550 + sElementsHTML = nullptr; 1.1551 + 1.1552 + delete sAttributesHTML; 1.1553 + sAttributesHTML = nullptr; 1.1554 + 1.1555 + delete sPresAttributesHTML; 1.1556 + sPresAttributesHTML = nullptr; 1.1557 + 1.1558 + delete sElementsSVG; 1.1559 + sElementsSVG = nullptr; 1.1560 + 1.1561 + delete sAttributesSVG; 1.1562 + sAttributesSVG = nullptr; 1.1563 + 1.1564 + delete sElementsMathML; 1.1565 + sElementsMathML = nullptr; 1.1566 + 1.1567 + delete sAttributesMathML; 1.1568 + sAttributesMathML = nullptr; 1.1569 + 1.1570 + NS_IF_RELEASE(sNullPrincipal); 1.1571 +}