Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
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 | } |