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