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