dompurify 2.2.8 → 2.3.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 +3 -3
- package/dist/purify.cjs.js +63 -20
- package/dist/purify.cjs.js.map +1 -1
- package/dist/purify.es.js +63 -20
- package/dist/purify.es.js.map +1 -1
- package/dist/purify.js +63 -20
- package/dist/purify.js.map +1 -1
- package/dist/purify.min.js +2 -2
- package/dist/purify.min.js.map +1 -1
- package/package.json +10 -11
package/dist/purify.es.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! @license DOMPurify | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/2.
|
|
1
|
+
/*! @license DOMPurify 2.3.2 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/2.3.2/LICENSE */
|
|
2
2
|
|
|
3
3
|
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
|
|
4
4
|
|
|
@@ -243,7 +243,7 @@ function createDOMPurify() {
|
|
|
243
243
|
* Version label, exposed for easier checks
|
|
244
244
|
* if DOMPurify is up to date or not
|
|
245
245
|
*/
|
|
246
|
-
DOMPurify.version = '2.2
|
|
246
|
+
DOMPurify.version = '2.3.2';
|
|
247
247
|
|
|
248
248
|
/**
|
|
249
249
|
* Array of elements that DOMPurify removed during sanitation.
|
|
@@ -301,7 +301,8 @@ function createDOMPurify() {
|
|
|
301
301
|
var _document = document,
|
|
302
302
|
implementation = _document.implementation,
|
|
303
303
|
createNodeIterator = _document.createNodeIterator,
|
|
304
|
-
createDocumentFragment = _document.createDocumentFragment
|
|
304
|
+
createDocumentFragment = _document.createDocumentFragment,
|
|
305
|
+
getElementsByTagName = _document.getElementsByTagName;
|
|
305
306
|
var importNode = originalDocument.importNode;
|
|
306
307
|
|
|
307
308
|
|
|
@@ -408,7 +409,8 @@ function createDOMPurify() {
|
|
|
408
409
|
var USE_PROFILES = {};
|
|
409
410
|
|
|
410
411
|
/* Tags to ignore content of when KEEP_CONTENT is true */
|
|
411
|
-
var FORBID_CONTENTS =
|
|
412
|
+
var FORBID_CONTENTS = null;
|
|
413
|
+
var DEFAULT_FORBID_CONTENTS = addToSet({}, ['annotation-xml', 'audio', 'colgroup', 'desc', 'foreignobject', 'head', 'iframe', 'math', 'mi', 'mn', 'mo', 'ms', 'mtext', 'noembed', 'noframes', 'noscript', 'plaintext', 'script', 'style', 'svg', 'template', 'thead', 'title', 'video', 'xmp']);
|
|
412
414
|
|
|
413
415
|
/* Tags that are safe for data: URIs */
|
|
414
416
|
var DATA_URI_TAGS = null;
|
|
@@ -416,13 +418,20 @@ function createDOMPurify() {
|
|
|
416
418
|
|
|
417
419
|
/* Attributes safe for values like "javascript:" */
|
|
418
420
|
var URI_SAFE_ATTRIBUTES = null;
|
|
419
|
-
var DEFAULT_URI_SAFE_ATTRIBUTES = addToSet({}, ['alt', 'class', 'for', 'id', 'label', 'name', 'pattern', 'placeholder', 'summary', 'title', 'value', 'style', 'xmlns']);
|
|
421
|
+
var DEFAULT_URI_SAFE_ATTRIBUTES = addToSet({}, ['alt', 'class', 'for', 'id', 'label', 'name', 'pattern', 'placeholder', 'role', 'summary', 'title', 'value', 'style', 'xmlns']);
|
|
420
422
|
|
|
421
423
|
var MATHML_NAMESPACE = 'http://www.w3.org/1998/Math/MathML';
|
|
422
424
|
var SVG_NAMESPACE = 'http://www.w3.org/2000/svg';
|
|
423
425
|
var HTML_NAMESPACE = 'http://www.w3.org/1999/xhtml';
|
|
424
426
|
/* Document namespace */
|
|
425
427
|
var NAMESPACE = HTML_NAMESPACE;
|
|
428
|
+
var IS_EMPTY_INPUT = false;
|
|
429
|
+
|
|
430
|
+
/* Parsing of strict XHTML documents */
|
|
431
|
+
var PARSER_MEDIA_TYPE = void 0;
|
|
432
|
+
var SUPPORTED_PARSER_MEDIA_TYPES = ['application/xhtml+xml', 'text/html'];
|
|
433
|
+
var DEFAULT_PARSER_MEDIA_TYPE = 'text/html';
|
|
434
|
+
var transformCaseFunc = void 0;
|
|
426
435
|
|
|
427
436
|
/* Keep a reference to config to pass to hooks */
|
|
428
437
|
var CONFIG = null;
|
|
@@ -456,6 +465,7 @@ function createDOMPurify() {
|
|
|
456
465
|
ALLOWED_ATTR = 'ALLOWED_ATTR' in cfg ? addToSet({}, cfg.ALLOWED_ATTR) : DEFAULT_ALLOWED_ATTR;
|
|
457
466
|
URI_SAFE_ATTRIBUTES = 'ADD_URI_SAFE_ATTR' in cfg ? addToSet(clone(DEFAULT_URI_SAFE_ATTRIBUTES), cfg.ADD_URI_SAFE_ATTR) : DEFAULT_URI_SAFE_ATTRIBUTES;
|
|
458
467
|
DATA_URI_TAGS = 'ADD_DATA_URI_TAGS' in cfg ? addToSet(clone(DEFAULT_DATA_URI_TAGS), cfg.ADD_DATA_URI_TAGS) : DEFAULT_DATA_URI_TAGS;
|
|
468
|
+
FORBID_CONTENTS = 'FORBID_CONTENTS' in cfg ? addToSet({}, cfg.FORBID_CONTENTS) : DEFAULT_FORBID_CONTENTS;
|
|
459
469
|
FORBID_TAGS = 'FORBID_TAGS' in cfg ? addToSet({}, cfg.FORBID_TAGS) : {};
|
|
460
470
|
FORBID_ATTR = 'FORBID_ATTR' in cfg ? addToSet({}, cfg.FORBID_ATTR) : {};
|
|
461
471
|
USE_PROFILES = 'USE_PROFILES' in cfg ? cfg.USE_PROFILES : false;
|
|
@@ -473,7 +483,13 @@ function createDOMPurify() {
|
|
|
473
483
|
KEEP_CONTENT = cfg.KEEP_CONTENT !== false; // Default true
|
|
474
484
|
IN_PLACE = cfg.IN_PLACE || false; // Default false
|
|
475
485
|
IS_ALLOWED_URI$$1 = cfg.ALLOWED_URI_REGEXP || IS_ALLOWED_URI$$1;
|
|
476
|
-
NAMESPACE = cfg.NAMESPACE ||
|
|
486
|
+
NAMESPACE = cfg.NAMESPACE || HTML_NAMESPACE;
|
|
487
|
+
PARSER_MEDIA_TYPE = cfg.PARSER_MEDIA_TYPE in SUPPORTED_PARSER_MEDIA_TYPES ? cfg.PARSER_MEDIA_TYPE : DEFAULT_PARSER_MEDIA_TYPE;
|
|
488
|
+
// HTML tags and attributes are not case-sensitive, converting to lowercase. Keeping XHTML as is.
|
|
489
|
+
transformCaseFunc = PARSER_MEDIA_TYPE === 'application/xhtml+xml' ? function (x) {
|
|
490
|
+
return x;
|
|
491
|
+
} : stringToLowerCase;
|
|
492
|
+
|
|
477
493
|
if (SAFE_FOR_TEMPLATES) {
|
|
478
494
|
ALLOW_DATA_ATTR = false;
|
|
479
495
|
}
|
|
@@ -531,6 +547,14 @@ function createDOMPurify() {
|
|
|
531
547
|
addToSet(URI_SAFE_ATTRIBUTES, cfg.ADD_URI_SAFE_ATTR);
|
|
532
548
|
}
|
|
533
549
|
|
|
550
|
+
if (cfg.FORBID_CONTENTS) {
|
|
551
|
+
if (FORBID_CONTENTS === DEFAULT_FORBID_CONTENTS) {
|
|
552
|
+
FORBID_CONTENTS = clone(FORBID_CONTENTS);
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
addToSet(FORBID_CONTENTS, cfg.FORBID_CONTENTS);
|
|
556
|
+
}
|
|
557
|
+
|
|
534
558
|
/* Add #text in case KEEP_CONTENT is set to true */
|
|
535
559
|
if (KEEP_CONTENT) {
|
|
536
560
|
ALLOWED_TAGS['#text'] = true;
|
|
@@ -669,6 +693,7 @@ function createDOMPurify() {
|
|
|
669
693
|
var _forceRemove = function _forceRemove(node) {
|
|
670
694
|
arrayPush(DOMPurify.removed, { element: node });
|
|
671
695
|
try {
|
|
696
|
+
// eslint-disable-next-line unicorn/prefer-dom-node-remove
|
|
672
697
|
node.parentNode.removeChild(node);
|
|
673
698
|
} catch (_) {
|
|
674
699
|
try {
|
|
@@ -733,6 +758,11 @@ function createDOMPurify() {
|
|
|
733
758
|
leadingWhitespace = matches && matches[0];
|
|
734
759
|
}
|
|
735
760
|
|
|
761
|
+
if (PARSER_MEDIA_TYPE === 'application/xhtml+xml') {
|
|
762
|
+
// Root of XHTML doc must contain xmlns declaration (see https://www.w3.org/TR/xhtml1/normative.html#strict)
|
|
763
|
+
dirty = '<html xmlns="http://www.w3.org/1999/xhtml"><head></head><body>' + dirty + '</body></html>';
|
|
764
|
+
}
|
|
765
|
+
|
|
736
766
|
var dirtyPayload = trustedTypesPolicy ? trustedTypesPolicy.createHTML(dirty) : dirty;
|
|
737
767
|
/*
|
|
738
768
|
* Use the DOMParser API by default, fallback later if needs be
|
|
@@ -740,14 +770,18 @@ function createDOMPurify() {
|
|
|
740
770
|
*/
|
|
741
771
|
if (NAMESPACE === HTML_NAMESPACE) {
|
|
742
772
|
try {
|
|
743
|
-
doc = new DOMParser().parseFromString(dirtyPayload,
|
|
773
|
+
doc = new DOMParser().parseFromString(dirtyPayload, PARSER_MEDIA_TYPE);
|
|
744
774
|
} catch (_) {}
|
|
745
775
|
}
|
|
746
776
|
|
|
747
777
|
/* Use createHTMLDocument in case DOMParser is not available */
|
|
748
778
|
if (!doc || !doc.documentElement) {
|
|
749
779
|
doc = implementation.createDocument(NAMESPACE, 'template', null);
|
|
750
|
-
|
|
780
|
+
try {
|
|
781
|
+
doc.documentElement.innerHTML = IS_EMPTY_INPUT ? '' : dirtyPayload;
|
|
782
|
+
} catch (_) {
|
|
783
|
+
// Syntax error if dirtyPayload is invalid xml
|
|
784
|
+
}
|
|
751
785
|
}
|
|
752
786
|
|
|
753
787
|
var body = doc.body || doc.documentElement;
|
|
@@ -757,6 +791,10 @@ function createDOMPurify() {
|
|
|
757
791
|
}
|
|
758
792
|
|
|
759
793
|
/* Work on whole document or just its body */
|
|
794
|
+
if (NAMESPACE === HTML_NAMESPACE) {
|
|
795
|
+
return getElementsByTagName.call(doc, WHOLE_DOCUMENT ? 'html' : 'body')[0];
|
|
796
|
+
}
|
|
797
|
+
|
|
760
798
|
return WHOLE_DOCUMENT ? doc.documentElement : body;
|
|
761
799
|
};
|
|
762
800
|
|
|
@@ -767,9 +805,7 @@ function createDOMPurify() {
|
|
|
767
805
|
* @return {Iterator} iterator instance
|
|
768
806
|
*/
|
|
769
807
|
var _createIterator = function _createIterator(root) {
|
|
770
|
-
return createNodeIterator.call(root.ownerDocument || root, root, NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_TEXT,
|
|
771
|
-
return NodeFilter.FILTER_ACCEPT;
|
|
772
|
-
}, false);
|
|
808
|
+
return createNodeIterator.call(root.ownerDocument || root, root, NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_TEXT, null, false);
|
|
773
809
|
};
|
|
774
810
|
|
|
775
811
|
/**
|
|
@@ -847,7 +883,7 @@ function createDOMPurify() {
|
|
|
847
883
|
}
|
|
848
884
|
|
|
849
885
|
/* Now let's check the element's type and name */
|
|
850
|
-
var tagName =
|
|
886
|
+
var tagName = transformCaseFunc(currentNode.nodeName);
|
|
851
887
|
|
|
852
888
|
/* Execute a hook if present */
|
|
853
889
|
_executeHook('uponSanitizeElement', currentNode, {
|
|
@@ -861,6 +897,12 @@ function createDOMPurify() {
|
|
|
861
897
|
return true;
|
|
862
898
|
}
|
|
863
899
|
|
|
900
|
+
/* Mitigate a problem with templates inside select */
|
|
901
|
+
if (tagName === 'select' && regExpTest(/<template/i, currentNode.innerHTML)) {
|
|
902
|
+
_forceRemove(currentNode);
|
|
903
|
+
return true;
|
|
904
|
+
}
|
|
905
|
+
|
|
864
906
|
/* Remove element if anything forbids its presence */
|
|
865
907
|
if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) {
|
|
866
908
|
/* Keep content except for bad-listed elements */
|
|
@@ -929,7 +971,7 @@ function createDOMPurify() {
|
|
|
929
971
|
(https://html.spec.whatwg.org/multipage/dom.html#embedding-custom-non-visible-data-with-the-data-*-attributes)
|
|
930
972
|
XML-compatible (https://html.spec.whatwg.org/multipage/infrastructure.html#xml-compatible and http://www.w3.org/TR/xml/#d0e804)
|
|
931
973
|
We don't need to check the value; it's always URI safe. */
|
|
932
|
-
if (ALLOW_DATA_ATTR && regExpTest(DATA_ATTR$$1, lcName)) ; else if (ALLOW_ARIA_ATTR && regExpTest(ARIA_ATTR$$1, lcName)) ; else if (!ALLOWED_ATTR[lcName] || FORBID_ATTR[lcName]) {
|
|
974
|
+
if (ALLOW_DATA_ATTR && !FORBID_ATTR[lcName] && regExpTest(DATA_ATTR$$1, lcName)) ; else if (ALLOW_ARIA_ATTR && regExpTest(ARIA_ATTR$$1, lcName)) ; else if (!ALLOWED_ATTR[lcName] || FORBID_ATTR[lcName]) {
|
|
933
975
|
return false;
|
|
934
976
|
|
|
935
977
|
/* Check value is safe. First, is attr inert? If so, is safe */
|
|
@@ -982,7 +1024,7 @@ function createDOMPurify() {
|
|
|
982
1024
|
namespaceURI = _attr.namespaceURI;
|
|
983
1025
|
|
|
984
1026
|
value = stringTrim(attr.value);
|
|
985
|
-
lcName =
|
|
1027
|
+
lcName = transformCaseFunc(name);
|
|
986
1028
|
|
|
987
1029
|
/* Execute a hook if present */
|
|
988
1030
|
hookEvent.attrName = lcName;
|
|
@@ -1017,7 +1059,7 @@ function createDOMPurify() {
|
|
|
1017
1059
|
}
|
|
1018
1060
|
|
|
1019
1061
|
/* Is `value` valid for this attribute? */
|
|
1020
|
-
var lcTag = currentNode.nodeName
|
|
1062
|
+
var lcTag = transformCaseFunc(currentNode.nodeName);
|
|
1021
1063
|
if (!_isValidAttribute(lcTag, lcName, value)) {
|
|
1022
1064
|
continue;
|
|
1023
1065
|
}
|
|
@@ -1090,7 +1132,8 @@ function createDOMPurify() {
|
|
|
1090
1132
|
/* Make sure we have a string to sanitize.
|
|
1091
1133
|
DO NOT return early, as this will return the wrong type if
|
|
1092
1134
|
the user has requested a DOM object rather than a string */
|
|
1093
|
-
|
|
1135
|
+
IS_EMPTY_INPUT = !dirty;
|
|
1136
|
+
if (IS_EMPTY_INPUT) {
|
|
1094
1137
|
dirty = '<!-->';
|
|
1095
1138
|
}
|
|
1096
1139
|
|
|
@@ -1146,7 +1189,7 @@ function createDOMPurify() {
|
|
|
1146
1189
|
} else if (importedNode.nodeName === 'HTML') {
|
|
1147
1190
|
body = importedNode;
|
|
1148
1191
|
} else {
|
|
1149
|
-
// eslint-disable-next-line unicorn/prefer-node-append
|
|
1192
|
+
// eslint-disable-next-line unicorn/prefer-dom-node-append
|
|
1150
1193
|
body.appendChild(importedNode);
|
|
1151
1194
|
}
|
|
1152
1195
|
} else {
|
|
@@ -1210,7 +1253,7 @@ function createDOMPurify() {
|
|
|
1210
1253
|
returnNode = createDocumentFragment.call(body.ownerDocument);
|
|
1211
1254
|
|
|
1212
1255
|
while (body.firstChild) {
|
|
1213
|
-
// eslint-disable-next-line unicorn/prefer-node-append
|
|
1256
|
+
// eslint-disable-next-line unicorn/prefer-dom-node-append
|
|
1214
1257
|
returnNode.appendChild(body.firstChild);
|
|
1215
1258
|
}
|
|
1216
1259
|
} else {
|
|
@@ -1279,8 +1322,8 @@ function createDOMPurify() {
|
|
|
1279
1322
|
_parseConfig({});
|
|
1280
1323
|
}
|
|
1281
1324
|
|
|
1282
|
-
var lcTag =
|
|
1283
|
-
var lcName =
|
|
1325
|
+
var lcTag = transformCaseFunc(tag);
|
|
1326
|
+
var lcName = transformCaseFunc(attr);
|
|
1284
1327
|
return _isValidAttribute(lcTag, lcName, value);
|
|
1285
1328
|
};
|
|
1286
1329
|
|