dompurify 2.1.0 → 2.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -8
- package/dist/purify.cjs.js +18 -53
- package/dist/purify.cjs.js.map +1 -1
- package/dist/purify.es.js +18 -53
- package/dist/purify.es.js.map +1 -1
- package/dist/purify.js +18 -53
- package/dist/purify.js.map +1 -1
- package/dist/purify.min.js +1 -1
- package/dist/purify.min.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -6,11 +6,11 @@
|
|
|
6
6
|
|
|
7
7
|
DOMPurify is a DOM-only, super-fast, uber-tolerant XSS sanitizer for HTML, MathML and SVG.
|
|
8
8
|
|
|
9
|
-
It's also very simple to use and get started with. DOMPurify was [started in February 2014](https://github.com/cure53/DOMPurify/commit/a630922616927373485e0e787ab19e73e3691b2b) and, meanwhile, has reached version 2.
|
|
9
|
+
It's also very simple to use and get started with. DOMPurify was [started in February 2014](https://github.com/cure53/DOMPurify/commit/a630922616927373485e0e787ab19e73e3691b2b) and, meanwhile, has reached version 2.2.2.
|
|
10
10
|
|
|
11
|
-
DOMPurify is written in JavaScript and works in all modern browsers (Safari, Opera (15+), Internet Explorer (10+), Edge, Firefox and Chrome - as well as almost anything else using Blink or WebKit). It doesn't break on MSIE6 or other legacy browsers. It either uses [a fall-back](#what-about-older-browsers-like-msie8) or simply does nothing.
|
|
11
|
+
DOMPurify is written in JavaScript and works in all modern browsers (Safari (10+), Opera (15+), Internet Explorer (10+), Edge, Firefox and Chrome - as well as almost anything else using Blink or WebKit). It doesn't break on MSIE6 or other legacy browsers. It either uses [a fall-back](#what-about-older-browsers-like-msie8) or simply does nothing.
|
|
12
12
|
|
|
13
|
-
Our automated tests cover [15 different browsers](https://github.com/cure53/DOMPurify/blob/main/test/karma.custom-launchers.config.js#L5) right now, more to come. We also cover Node.js v12
|
|
13
|
+
Our automated tests cover [15 different browsers](https://github.com/cure53/DOMPurify/blob/main/test/karma.custom-launchers.config.js#L5) right now, more to come. We also cover Node.js v12, v13, v14.0.0, running DOMPurify on [jsdom](https://github.com/tmpvar/jsdom). Older Node.js versions are known to work as well.
|
|
14
14
|
|
|
15
15
|
DOMPurify is written by security people who have vast background in web attacks and XSS. Fear not. For more details please also read about our [Security Goals & Threat Model](https://github.com/cure53/DOMPurify/wiki/Security-Goals-&-Threat-Model). Please, read it. Like, really.
|
|
16
16
|
|
|
@@ -46,8 +46,6 @@ The resulting HTML can be written into a DOM element using `innerHTML` or the DO
|
|
|
46
46
|
|
|
47
47
|
Well, please note, if you _first_ sanitize HTML and then modify it _afterwards_, you might easily **void the effects of sanitization**. If you feed the sanitized markup to another library _after_ sanitization, please be certain that the library doesn't mess around with the HTML on its own.
|
|
48
48
|
|
|
49
|
-
jQuery does exactly that and that is why we have this flag mentioned above.
|
|
50
|
-
|
|
51
49
|
### Okay, makes sense, let's move on
|
|
52
50
|
|
|
53
51
|
After sanitizing your markup, you can also have a look at the property `DOMPurify.removed` and find out, what elements and attributes were thrown out. Please **do not use** this property for making any security critical decisions. This is just a little helper for curious minds.
|
|
@@ -107,7 +105,7 @@ How does purified markup look like? Well, [the demo](https://cure53.de/purify) s
|
|
|
107
105
|
```js
|
|
108
106
|
DOMPurify.sanitize('<img src=x onerror=alert(1)//>'); // becomes <img src="x">
|
|
109
107
|
DOMPurify.sanitize('<svg><g/onload=alert(2)//<p>'); // becomes <svg><g></g></svg>
|
|
110
|
-
DOMPurify.sanitize('<p>abc<iframe//src=jAva	script:alert(3)>def</p>'); // becomes <p>
|
|
108
|
+
DOMPurify.sanitize('<p>abc<iframe//src=jAva	script:alert(3)>def</p>'); // becomes <p>abc</p>
|
|
111
109
|
DOMPurify.sanitize('<math><mi//xlink:href="data:x,<script>alert(4)</script>">'); // becomes <math><mi></mi></math>
|
|
112
110
|
DOMPurify.sanitize('<TABLE><tr><td>HELLO</tr></TABL>'); // becomes <table><tbody><tr><td>HELLO</td></tr></tbody></table>
|
|
113
111
|
DOMPurify.sanitize('<UL><li><A HREF=//google.com>click</UL>'); // becomes <ul><li><a href="//google.com">click</a></li></ul>
|
|
@@ -203,6 +201,9 @@ var clean = DOMPurify.sanitize(dirty, {ALLOWED_URI_REGEXP: /^(?:(?:(?:f|ht)tps?|
|
|
|
203
201
|
|
|
204
202
|
/**
|
|
205
203
|
* Influence the return-type
|
|
204
|
+
*
|
|
205
|
+
* Careful, this setting has foot-gun potential! If you set RETURN_DOM or RETURN_DOM_FRAGMENT to true, don't set RETURN_DOM_IMPORT to false!
|
|
206
|
+
* By default, our settings are secure - we believe - but returning a DOM *and* manually setting RETURN_DOM_IMPORT to false will give you XSS in some situations.
|
|
206
207
|
*/
|
|
207
208
|
// return a DOM HTMLBodyElement instead of an HTML string (default is false)
|
|
208
209
|
var clean = DOMPurify.sanitize(dirty, {RETURN_DOM: true});
|
|
@@ -213,7 +214,7 @@ var clean = DOMPurify.sanitize(dirty, {RETURN_DOM_FRAGMENT: true});
|
|
|
213
214
|
// return a DOM DocumentFragment instead of an HTML string (default is false)
|
|
214
215
|
// also import it into the current document (default is false).
|
|
215
216
|
// RETURN_DOM_IMPORT must be set if you would like to append
|
|
216
|
-
// the returned node to the current document
|
|
217
|
+
// the returned node to the current document (default is true)
|
|
217
218
|
var clean = DOMPurify.sanitize(dirty, {RETURN_DOM_FRAGMENT: true, RETURN_DOM_IMPORT: true});
|
|
218
219
|
document.body.appendChild(clean);
|
|
219
220
|
|
|
@@ -326,7 +327,7 @@ Feature releases will not be announced to this list.
|
|
|
326
327
|
|
|
327
328
|
Many people helped and help DOMPurify become what it is and need to be acknowledged here!
|
|
328
329
|
|
|
329
|
-
[oreoshake 💸](https://github.com/oreoshake), [dcramer 💸](https://github.com/dcramer),[tdeekens ❤️](https://github.com/tdeekens), [peernohell ❤️](https://github.com/peernohell), [neilj](https://github.com/neilj), [fhemberger](https://github.com/fhemberger), [Joris-van-der-Wel](https://github.com/Joris-van-der-Wel), [ydaniv](https://github.com/ydaniv), [filedescriptor](https://github.com/filedescriptor), [ConradIrwin](https://github.com/ConradIrwin), [gibson042](https://github.com/gibson042), [choumx](https://github.com/choumx), [0xSobky](https://github.com/0xSobky), [styfle](https://github.com/styfle), [koto](https://github.com/koto), [tlau88](https://github.com/tlau88), [strugee](https://github.com/strugee), [oparoz](https://github.com/oparoz), [mathiasbynens](https://github.com/mathiasbynens), [edg2s](https://github.com/edg2s), [dnkolegov](https://github.com/dnkolegov), [dhardtke](https://github.com/dhardtke), [wirehead](https://github.com/wirehead), [thorn0](https://github.com/thorn0), [styu](https://github.com/styu), [mozfreddyb](https://github.com/mozfreddyb), [mikesamuel](https://github.com/mikesamuel), [jorangreef](https://github.com/jorangreef), [jimmyhchan](https://github.com/jimmyhchan), [jameydeorio](https://github.com/jameydeorio), [jameskraus](https://github.com/jameskraus), [hyderali](https://github.com/hyderali), [hansottowirtz](https://github.com/hansottowirtz), [hackvertor](https://github.com/hackvertor), [freddyb](https://github.com/freddyb), [flavorjones](https://github.com/flavorjones), [djfarrelly](https://github.com/djfarrelly), [devd](https://github.com/devd), [camerondunford](https://github.com/camerondunford), [buu700](https://github.com/buu700), [buildog](https://github.com/buildog), [alabiaga](https://github.com/alabiaga), [Vector919](https://github.com/Vector919), [Robbert](https://github.com/Robbert), [GreLI](https://github.com/GreLI), [FuzzySockets](https://github.com/FuzzySockets), [ArtemBernatskyy](https://github.com/ArtemBernatskyy), [@garethheyes](https://twitter.com/garethheyes), [@
|
|
330
|
+
[oreoshake 💸](https://github.com/oreoshake), [dcramer 💸](https://github.com/dcramer),[tdeekens ❤️](https://github.com/tdeekens), [peernohell ❤️](https://github.com/peernohell), [neilj](https://github.com/neilj), [fhemberger](https://github.com/fhemberger), [Joris-van-der-Wel](https://github.com/Joris-van-der-Wel), [ydaniv](https://github.com/ydaniv), [terjanq](https://twitter.com/terjanq), [filedescriptor](https://github.com/filedescriptor), [ConradIrwin](https://github.com/ConradIrwin), [gibson042](https://github.com/gibson042), [choumx](https://github.com/choumx), [0xSobky](https://github.com/0xSobky), [styfle](https://github.com/styfle), [koto](https://github.com/koto), [tlau88](https://github.com/tlau88), [strugee](https://github.com/strugee), [oparoz](https://github.com/oparoz), [mathiasbynens](https://github.com/mathiasbynens), [edg2s](https://github.com/edg2s), [dnkolegov](https://github.com/dnkolegov), [dhardtke](https://github.com/dhardtke), [wirehead](https://github.com/wirehead), [thorn0](https://github.com/thorn0), [styu](https://github.com/styu), [mozfreddyb](https://github.com/mozfreddyb), [mikesamuel](https://github.com/mikesamuel), [jorangreef](https://github.com/jorangreef), [jimmyhchan](https://github.com/jimmyhchan), [jameydeorio](https://github.com/jameydeorio), [jameskraus](https://github.com/jameskraus), [hyderali](https://github.com/hyderali), [hansottowirtz](https://github.com/hansottowirtz), [hackvertor](https://github.com/hackvertor), [freddyb](https://github.com/freddyb), [flavorjones](https://github.com/flavorjones), [djfarrelly](https://github.com/djfarrelly), [devd](https://github.com/devd), [camerondunford](https://github.com/camerondunford), [buu700](https://github.com/buu700), [buildog](https://github.com/buildog), [alabiaga](https://github.com/alabiaga), [Vector919](https://github.com/Vector919), [Robbert](https://github.com/Robbert), [GreLI](https://github.com/GreLI), [FuzzySockets](https://github.com/FuzzySockets), [ArtemBernatskyy](https://github.com/ArtemBernatskyy), [@garethheyes](https://twitter.com/garethheyes), [@shafigullin](https://twitter.com/shafigullin), [@mmrupp](https://twitter.com/mmrupp), [@irsdl](https://twitter.com/irsdl),[ShikariSenpai](https://github.com/ShikariSenpai), [ansjdnakjdnajkd](https://github.com/ansjdnakjdnajkd), [@asutherland](https://twitter.com/asutherland), [@mathias](https://twitter.com/mathias), [@cgvwzq](https://twitter.com/cgvwzq), [@robbertatwork](https://twitter.com/robbertatwork), [@giutro](https://twitter.com/giutro) and especially [@masatokinugawa](https://twitter.com/masatokinugawa)
|
|
330
331
|
|
|
331
332
|
## Testing powered by
|
|
332
333
|
<a target="_blank" href="https://www.browserstack.com/"><img width="200" src="https://www.browserstack.com/images/layout/browserstack-logo-600x315.png"></a><br>
|
package/dist/purify.cjs.js
CHANGED
|
@@ -40,10 +40,8 @@ if (!construct) {
|
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
var arrayForEach = unapply(Array.prototype.forEach);
|
|
43
|
-
var arrayIndexOf = unapply(Array.prototype.indexOf);
|
|
44
43
|
var arrayPop = unapply(Array.prototype.pop);
|
|
45
44
|
var arrayPush = unapply(Array.prototype.push);
|
|
46
|
-
var arraySlice = unapply(Array.prototype.slice);
|
|
47
45
|
|
|
48
46
|
var stringToLowerCase = unapply(String.prototype.toLowerCase);
|
|
49
47
|
var stringMatch = unapply(String.prototype.match);
|
|
@@ -119,7 +117,7 @@ function clone(object) {
|
|
|
119
117
|
return newObject;
|
|
120
118
|
}
|
|
121
119
|
|
|
122
|
-
var html = freeze(['a', 'abbr', 'acronym', 'address', 'area', 'article', 'aside', 'audio', 'b', 'bdi', 'bdo', 'big', 'blink', 'blockquote', 'body', 'br', 'button', 'canvas', 'caption', 'center', 'cite', 'code', 'col', 'colgroup', 'content', 'data', 'datalist', 'dd', 'decorator', 'del', 'details', 'dfn', 'dir', 'div', 'dl', 'dt', 'element', 'em', 'fieldset', 'figcaption', 'figure', 'font', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'header', 'hgroup', 'hr', 'html', 'i', 'img', 'input', 'ins', 'kbd', 'label', 'legend', 'li', 'main', 'map', 'mark', 'marquee', 'menu', 'menuitem', 'meter', 'nav', 'nobr', 'ol', 'optgroup', 'option', 'output', 'p', 'picture', 'pre', 'progress', 'q', 'rp', 'rt', 'ruby', 's', 'samp', 'section', 'select', 'shadow', 'small', 'source', 'spacer', 'span', 'strike', 'strong', 'style', 'sub', 'summary', 'sup', 'table', 'tbody', 'td', 'template', 'textarea', 'tfoot', 'th', 'thead', 'time', 'tr', 'track', 'tt', 'u', 'ul', 'var', 'video', 'wbr']);
|
|
120
|
+
var html = freeze(['a', 'abbr', 'acronym', 'address', 'area', 'article', 'aside', 'audio', 'b', 'bdi', 'bdo', 'big', 'blink', 'blockquote', 'body', 'br', 'button', 'canvas', 'caption', 'center', 'cite', 'code', 'col', 'colgroup', 'content', 'data', 'datalist', 'dd', 'decorator', 'del', 'details', 'dfn', 'dialog', 'dir', 'div', 'dl', 'dt', 'element', 'em', 'fieldset', 'figcaption', 'figure', 'font', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'header', 'hgroup', 'hr', 'html', 'i', 'img', 'input', 'ins', 'kbd', 'label', 'legend', 'li', 'main', 'map', 'mark', 'marquee', 'menu', 'menuitem', 'meter', 'nav', 'nobr', 'ol', 'optgroup', 'option', 'output', 'p', 'picture', 'pre', 'progress', 'q', 'rp', 'rt', 'ruby', 's', 'samp', 'section', 'select', 'shadow', 'small', 'source', 'spacer', 'span', 'strike', 'strong', 'style', 'sub', 'summary', 'sup', 'table', 'tbody', 'td', 'template', 'textarea', 'tfoot', 'th', 'thead', 'time', 'tr', 'track', 'tt', 'u', 'ul', 'var', 'video', 'wbr']);
|
|
123
121
|
|
|
124
122
|
// SVG
|
|
125
123
|
var svg = freeze(['svg', 'a', 'altglyph', 'altglyphdef', 'altglyphitem', 'animatecolor', 'animatemotion', 'animatetransform', 'audio', 'canvas', 'circle', 'clippath', 'defs', 'desc', 'ellipse', 'filter', 'font', 'g', 'glyph', 'glyphref', 'hkern', 'image', 'line', 'lineargradient', 'marker', 'mask', 'metadata', 'mpath', 'path', 'pattern', 'polygon', 'polyline', 'radialgradient', 'rect', 'stop', 'style', 'switch', 'symbol', 'text', 'textpath', 'title', 'tref', 'tspan', 'video', 'view', 'vkern']);
|
|
@@ -207,7 +205,7 @@ function createDOMPurify() {
|
|
|
207
205
|
* Version label, exposed for easier checks
|
|
208
206
|
* if DOMPurify is up to date or not
|
|
209
207
|
*/
|
|
210
|
-
DOMPurify.version = '2.
|
|
208
|
+
DOMPurify.version = '2.2.2';
|
|
211
209
|
|
|
212
210
|
/**
|
|
213
211
|
* Array of elements that DOMPurify removed during sanitation.
|
|
@@ -224,7 +222,6 @@ function createDOMPurify() {
|
|
|
224
222
|
}
|
|
225
223
|
|
|
226
224
|
var originalDocument = window.document;
|
|
227
|
-
var removeTitle = false;
|
|
228
225
|
|
|
229
226
|
var document = window.document;
|
|
230
227
|
var DocumentFragment = window.DocumentFragment,
|
|
@@ -340,8 +337,13 @@ function createDOMPurify() {
|
|
|
340
337
|
/* If `RETURN_DOM` or `RETURN_DOM_FRAGMENT` is enabled, decide if the returned DOM
|
|
341
338
|
* `Node` is imported into the current `Document`. If this flag is not enabled the
|
|
342
339
|
* `Node` will belong (its ownerDocument) to a fresh `HTMLDocument`, created by
|
|
343
|
-
* DOMPurify.
|
|
344
|
-
|
|
340
|
+
* DOMPurify.
|
|
341
|
+
*
|
|
342
|
+
* This defaults to `true` starting DOMPurify 2.2.0. Note that setting it to `false`
|
|
343
|
+
* might cause XSS from attacks hidden in closed shadowroots in case the browser
|
|
344
|
+
* supports Declarative Shadow: DOM https://web.dev/declarative-shadow-dom/
|
|
345
|
+
*/
|
|
346
|
+
var RETURN_DOM_IMPORT = true;
|
|
345
347
|
|
|
346
348
|
/* Try to return a Trusted Type object instead of a string, return a string in
|
|
347
349
|
* case Trusted Types are not supported */
|
|
@@ -413,7 +415,7 @@ function createDOMPurify() {
|
|
|
413
415
|
WHOLE_DOCUMENT = cfg.WHOLE_DOCUMENT || false; // Default false
|
|
414
416
|
RETURN_DOM = cfg.RETURN_DOM || false; // Default false
|
|
415
417
|
RETURN_DOM_FRAGMENT = cfg.RETURN_DOM_FRAGMENT || false; // Default false
|
|
416
|
-
RETURN_DOM_IMPORT = cfg.RETURN_DOM_IMPORT
|
|
418
|
+
RETURN_DOM_IMPORT = cfg.RETURN_DOM_IMPORT !== false; // Default true
|
|
417
419
|
RETURN_TRUSTED_TYPE = cfg.RETURN_TRUSTED_TYPE || false; // Default false
|
|
418
420
|
FORCE_BODY = cfg.FORCE_BODY || false; // Default false
|
|
419
421
|
SANITIZE_DOM = cfg.SANITIZE_DOM !== false; // Default true
|
|
@@ -563,11 +565,6 @@ function createDOMPurify() {
|
|
|
563
565
|
doc = new DOMParser().parseFromString(dirtyPayload, 'text/html');
|
|
564
566
|
} catch (_) {}
|
|
565
567
|
|
|
566
|
-
/* Remove title to fix a mXSS bug in older MS Edge */
|
|
567
|
-
if (removeTitle) {
|
|
568
|
-
addToSet(FORBID_TAGS, ['title']);
|
|
569
|
-
}
|
|
570
|
-
|
|
571
568
|
/* Use createHTMLDocument in case DOMParser is not available */
|
|
572
569
|
if (!doc || !doc.documentElement) {
|
|
573
570
|
doc = implementation.createHTMLDocument('');
|
|
@@ -586,18 +583,6 @@ function createDOMPurify() {
|
|
|
586
583
|
return getElementsByTagName.call(doc, WHOLE_DOCUMENT ? 'html' : 'body')[0];
|
|
587
584
|
};
|
|
588
585
|
|
|
589
|
-
/* Here we test for a broken feature in Edge that might cause mXSS */
|
|
590
|
-
if (DOMPurify.isSupported) {
|
|
591
|
-
(function () {
|
|
592
|
-
try {
|
|
593
|
-
var doc = _initDocument('<x/><title></title><img>');
|
|
594
|
-
if (regExpTest(/<\/title/, doc.querySelector('title').innerHTML)) {
|
|
595
|
-
removeTitle = true;
|
|
596
|
-
}
|
|
597
|
-
} catch (_) {}
|
|
598
|
-
})();
|
|
599
|
-
}
|
|
600
|
-
|
|
601
586
|
/**
|
|
602
587
|
* _createIterator
|
|
603
588
|
*
|
|
@@ -693,6 +678,12 @@ function createDOMPurify() {
|
|
|
693
678
|
allowedTags: ALLOWED_TAGS
|
|
694
679
|
});
|
|
695
680
|
|
|
681
|
+
/* Take care of an mXSS pattern using p, br inside svg, math */
|
|
682
|
+
if ((tagName === 'svg' || tagName === 'math') && currentNode.querySelectorAll('p, br, form, table').length !== 0) {
|
|
683
|
+
_forceRemove(currentNode);
|
|
684
|
+
return true;
|
|
685
|
+
}
|
|
686
|
+
|
|
696
687
|
/* Detect mXSS attempts abusing namespace confusion */
|
|
697
688
|
if (!_isNode(currentNode.firstElementChild) && (!_isNode(currentNode.content) || !_isNode(currentNode.content.firstElementChild)) && regExpTest(/<[!/\w]/g, currentNode.innerHTML) && regExpTest(/<[!/\w]/g, currentNode.textContent)) {
|
|
698
689
|
_forceRemove(currentNode);
|
|
@@ -781,7 +772,6 @@ function createDOMPurify() {
|
|
|
781
772
|
var attr = void 0;
|
|
782
773
|
var value = void 0;
|
|
783
774
|
var lcName = void 0;
|
|
784
|
-
var idAttr = void 0;
|
|
785
775
|
var l = void 0;
|
|
786
776
|
/* Execute a hook if present */
|
|
787
777
|
_executeHook('beforeSanitizeAttributes', currentNode, null);
|
|
@@ -825,32 +815,7 @@ function createDOMPurify() {
|
|
|
825
815
|
}
|
|
826
816
|
|
|
827
817
|
/* Remove attribute */
|
|
828
|
-
|
|
829
|
-
// remove a "name" attribute from an <img> tag that has an "id"
|
|
830
|
-
// attribute at the time.
|
|
831
|
-
if (lcName === 'name' && currentNode.nodeName === 'IMG' && attributes.id) {
|
|
832
|
-
idAttr = attributes.id;
|
|
833
|
-
attributes = arraySlice(attributes, []);
|
|
834
|
-
_removeAttribute('id', currentNode);
|
|
835
|
-
_removeAttribute(name, currentNode);
|
|
836
|
-
if (arrayIndexOf(attributes, idAttr) > l) {
|
|
837
|
-
currentNode.setAttribute('id', idAttr.value);
|
|
838
|
-
}
|
|
839
|
-
} else if (
|
|
840
|
-
// This works around a bug in Safari, where input[type=file]
|
|
841
|
-
// cannot be dynamically set after type has been removed
|
|
842
|
-
currentNode.nodeName === 'INPUT' && lcName === 'type' && value === 'file' && hookEvent.keepAttr && (ALLOWED_ATTR[lcName] || !FORBID_ATTR[lcName])) {
|
|
843
|
-
continue;
|
|
844
|
-
} else {
|
|
845
|
-
// This avoids a crash in Safari v9.0 with double-ids.
|
|
846
|
-
// The trick is to first set the id to be empty and then to
|
|
847
|
-
// remove the attribute
|
|
848
|
-
if (name === 'id') {
|
|
849
|
-
currentNode.setAttribute(name, '');
|
|
850
|
-
}
|
|
851
|
-
|
|
852
|
-
_removeAttribute(name, currentNode);
|
|
853
|
-
}
|
|
818
|
+
_removeAttribute(name, currentNode);
|
|
854
819
|
|
|
855
820
|
/* Did the hooks approve of the attribute? */
|
|
856
821
|
if (!hookEvent.keepAttr) {
|
|
@@ -991,7 +956,7 @@ function createDOMPurify() {
|
|
|
991
956
|
if (IN_PLACE) ; else if (dirty instanceof Node) {
|
|
992
957
|
/* If dirty is a DOM element, append to an empty document to avoid
|
|
993
958
|
elements being stripped by the parser */
|
|
994
|
-
body = _initDocument('
|
|
959
|
+
body = _initDocument('<!---->');
|
|
995
960
|
importedNode = body.ownerDocument.importNode(dirty, true);
|
|
996
961
|
if (importedNode.nodeType === 1 && importedNode.nodeName === 'BODY') {
|
|
997
962
|
/* Node is already a body, use as is */
|