dompurify 3.0.5 → 3.0.6
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 +63 -70
- package/dist/purify.cjs.js +115 -75
- package/dist/purify.cjs.js.map +1 -1
- package/dist/purify.es.js +115 -75
- package/dist/purify.es.js.map +1 -1
- package/dist/purify.js +115 -75
- 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 +1 -1
package/dist/purify.es.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! @license DOMPurify 3.0.
|
|
1
|
+
/*! @license DOMPurify 3.0.6 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.0.6/LICENSE */
|
|
2
2
|
|
|
3
3
|
const {
|
|
4
4
|
entries,
|
|
@@ -18,12 +18,6 @@ let {
|
|
|
18
18
|
construct
|
|
19
19
|
} = typeof Reflect !== 'undefined' && Reflect;
|
|
20
20
|
|
|
21
|
-
if (!apply) {
|
|
22
|
-
apply = function apply(fun, thisValue, args) {
|
|
23
|
-
return fun.apply(thisValue, args);
|
|
24
|
-
};
|
|
25
|
-
}
|
|
26
|
-
|
|
27
21
|
if (!freeze) {
|
|
28
22
|
freeze = function freeze(x) {
|
|
29
23
|
return x;
|
|
@@ -36,6 +30,12 @@ if (!seal) {
|
|
|
36
30
|
};
|
|
37
31
|
}
|
|
38
32
|
|
|
33
|
+
if (!apply) {
|
|
34
|
+
apply = function apply(fun, thisValue, args) {
|
|
35
|
+
return fun.apply(thisValue, args);
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
|
|
39
39
|
if (!construct) {
|
|
40
40
|
construct = function construct(Func, args) {
|
|
41
41
|
return new Func(...args);
|
|
@@ -53,6 +53,13 @@ const stringIndexOf = unapply(String.prototype.indexOf);
|
|
|
53
53
|
const stringTrim = unapply(String.prototype.trim);
|
|
54
54
|
const regExpTest = unapply(RegExp.prototype.test);
|
|
55
55
|
const typeErrorCreate = unconstruct(TypeError);
|
|
56
|
+
/**
|
|
57
|
+
* Creates a new function that calls the given function with a specified thisArg and arguments.
|
|
58
|
+
*
|
|
59
|
+
* @param {Function} func - The function to be wrapped and called.
|
|
60
|
+
* @returns {Function} A new function that calls the given function with a specified thisArg and arguments.
|
|
61
|
+
*/
|
|
62
|
+
|
|
56
63
|
function unapply(func) {
|
|
57
64
|
return function (thisArg) {
|
|
58
65
|
for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
|
@@ -62,6 +69,14 @@ function unapply(func) {
|
|
|
62
69
|
return apply(func, thisArg, args);
|
|
63
70
|
};
|
|
64
71
|
}
|
|
72
|
+
/**
|
|
73
|
+
* Creates a new function that constructs an instance of the given constructor function with the provided arguments.
|
|
74
|
+
*
|
|
75
|
+
* @param {Function} func - The constructor function to be wrapped and called.
|
|
76
|
+
* @returns {Function} A new function that constructs an instance of the given constructor function with the provided arguments.
|
|
77
|
+
*/
|
|
78
|
+
|
|
79
|
+
|
|
65
80
|
function unconstruct(func) {
|
|
66
81
|
return function () {
|
|
67
82
|
for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
|
|
@@ -71,12 +86,18 @@ function unconstruct(func) {
|
|
|
71
86
|
return construct(func, args);
|
|
72
87
|
};
|
|
73
88
|
}
|
|
74
|
-
|
|
89
|
+
/**
|
|
90
|
+
* Add properties to a lookup table
|
|
91
|
+
*
|
|
92
|
+
* @param {Object} set - The set to which elements will be added.
|
|
93
|
+
* @param {Array} array - The array containing elements to be added to the set.
|
|
94
|
+
* @param {Function} transformCaseFunc - An optional function to transform the case of each element before adding to the set.
|
|
95
|
+
* @returns {Object} The modified set with added elements.
|
|
96
|
+
*/
|
|
75
97
|
|
|
76
|
-
function addToSet(set, array, transformCaseFunc) {
|
|
77
|
-
var _transformCaseFunc;
|
|
78
98
|
|
|
79
|
-
|
|
99
|
+
function addToSet(set, array) {
|
|
100
|
+
let transformCaseFunc = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : stringToLowerCase;
|
|
80
101
|
|
|
81
102
|
if (setPrototypeOf) {
|
|
82
103
|
// Make 'in' and truthy checks like Boolean(set.constructor)
|
|
@@ -108,19 +129,32 @@ function addToSet(set, array, transformCaseFunc) {
|
|
|
108
129
|
|
|
109
130
|
return set;
|
|
110
131
|
}
|
|
111
|
-
|
|
132
|
+
/**
|
|
133
|
+
* Shallow clone an object
|
|
134
|
+
*
|
|
135
|
+
* @param {Object} object - The object to be cloned.
|
|
136
|
+
* @returns {Object} A new object that copies the original.
|
|
137
|
+
*/
|
|
138
|
+
|
|
112
139
|
|
|
113
140
|
function clone(object) {
|
|
114
141
|
const newObject = create(null);
|
|
115
142
|
|
|
116
143
|
for (const [property, value] of entries(object)) {
|
|
117
|
-
|
|
144
|
+
if (getOwnPropertyDescriptor(object, property) !== undefined) {
|
|
145
|
+
newObject[property] = value;
|
|
146
|
+
}
|
|
118
147
|
}
|
|
119
148
|
|
|
120
149
|
return newObject;
|
|
121
150
|
}
|
|
122
|
-
|
|
123
|
-
* or getter and behaves accordingly.
|
|
151
|
+
/**
|
|
152
|
+
* This method automatically checks if the prop is function or getter and behaves accordingly.
|
|
153
|
+
*
|
|
154
|
+
* @param {Object} object - The object to look up the getter function in its prototype chain.
|
|
155
|
+
* @param {String} prop - The property name for which to find the getter function.
|
|
156
|
+
* @returns {Function} The getter function found in the prototype chain or a fallback function.
|
|
157
|
+
*/
|
|
124
158
|
|
|
125
159
|
function lookupGetter(object, prop) {
|
|
126
160
|
while (object !== null) {
|
|
@@ -195,7 +229,9 @@ var EXPRESSIONS = /*#__PURE__*/Object.freeze({
|
|
|
195
229
|
DOCTYPE_NAME: DOCTYPE_NAME
|
|
196
230
|
});
|
|
197
231
|
|
|
198
|
-
const getGlobal = ()
|
|
232
|
+
const getGlobal = function getGlobal() {
|
|
233
|
+
return typeof window === 'undefined' ? null : window;
|
|
234
|
+
};
|
|
199
235
|
/**
|
|
200
236
|
* Creates a no-op policy for internal use only.
|
|
201
237
|
* Don't export this function outside this module!
|
|
@@ -253,7 +289,7 @@ function createDOMPurify() {
|
|
|
253
289
|
*/
|
|
254
290
|
|
|
255
291
|
|
|
256
|
-
DOMPurify.version = '3.0.
|
|
292
|
+
DOMPurify.version = '3.0.6';
|
|
257
293
|
/**
|
|
258
294
|
* Array of elements that DOMPurify removed during sanitation.
|
|
259
295
|
* Empty if nothing was removed.
|
|
@@ -268,11 +304,11 @@ function createDOMPurify() {
|
|
|
268
304
|
return DOMPurify;
|
|
269
305
|
}
|
|
270
306
|
|
|
271
|
-
const originalDocument = window.document;
|
|
272
|
-
const currentScript = originalDocument.currentScript;
|
|
273
307
|
let {
|
|
274
308
|
document
|
|
275
309
|
} = window;
|
|
310
|
+
const originalDocument = document;
|
|
311
|
+
const currentScript = originalDocument.currentScript;
|
|
276
312
|
const {
|
|
277
313
|
DocumentFragment,
|
|
278
314
|
HTMLTemplateElement,
|
|
@@ -352,7 +388,7 @@ function createDOMPurify() {
|
|
|
352
388
|
* @property {boolean} allowCustomizedBuiltInElements allow custom elements derived from built-ins if they pass CUSTOM_ELEMENT_HANDLING.tagNameCheck. Default: `false`.
|
|
353
389
|
*/
|
|
354
390
|
|
|
355
|
-
let CUSTOM_ELEMENT_HANDLING = Object.seal(
|
|
391
|
+
let CUSTOM_ELEMENT_HANDLING = Object.seal(create(null, {
|
|
356
392
|
tagNameCheck: {
|
|
357
393
|
writable: true,
|
|
358
394
|
configurable: false,
|
|
@@ -476,10 +512,10 @@ function createDOMPurify() {
|
|
|
476
512
|
const DEFAULT_ALLOWED_NAMESPACES = addToSet({}, [MATHML_NAMESPACE, SVG_NAMESPACE, HTML_NAMESPACE], stringToString);
|
|
477
513
|
/* Parsing of strict XHTML documents */
|
|
478
514
|
|
|
479
|
-
let PARSER_MEDIA_TYPE;
|
|
515
|
+
let PARSER_MEDIA_TYPE = null;
|
|
480
516
|
const SUPPORTED_PARSER_MEDIA_TYPES = ['application/xhtml+xml', 'text/html'];
|
|
481
517
|
const DEFAULT_PARSER_MEDIA_TYPE = 'text/html';
|
|
482
|
-
let transformCaseFunc;
|
|
518
|
+
let transformCaseFunc = null;
|
|
483
519
|
/* Keep a reference to config to pass to hooks */
|
|
484
520
|
|
|
485
521
|
let CONFIG = null;
|
|
@@ -500,7 +536,9 @@ function createDOMPurify() {
|
|
|
500
536
|
// eslint-disable-next-line complexity
|
|
501
537
|
|
|
502
538
|
|
|
503
|
-
const _parseConfig = function _parseConfig(
|
|
539
|
+
const _parseConfig = function _parseConfig() {
|
|
540
|
+
let cfg = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
541
|
+
|
|
504
542
|
if (CONFIG && CONFIG === cfg) {
|
|
505
543
|
return;
|
|
506
544
|
}
|
|
@@ -719,8 +757,6 @@ function createDOMPurify() {
|
|
|
719
757
|
const ALL_MATHML_TAGS = addToSet({}, mathMl$1);
|
|
720
758
|
addToSet(ALL_MATHML_TAGS, mathMlDisallowed);
|
|
721
759
|
/**
|
|
722
|
-
*
|
|
723
|
-
*
|
|
724
760
|
* @param {Element} element a DOM element whose namespace is being checked
|
|
725
761
|
* @returns {boolean} Return false if the element has a
|
|
726
762
|
* namespace that a spec-compliant parser would never
|
|
@@ -876,8 +912,8 @@ function createDOMPurify() {
|
|
|
876
912
|
|
|
877
913
|
const _initDocument = function _initDocument(dirty) {
|
|
878
914
|
/* Create a HTML document */
|
|
879
|
-
let doc;
|
|
880
|
-
let leadingWhitespace;
|
|
915
|
+
let doc = null;
|
|
916
|
+
let leadingWhitespace = null;
|
|
881
917
|
|
|
882
918
|
if (FORCE_BODY) {
|
|
883
919
|
dirty = '<remove></remove>' + dirty;
|
|
@@ -930,16 +966,16 @@ function createDOMPurify() {
|
|
|
930
966
|
return WHOLE_DOCUMENT ? doc.documentElement : body;
|
|
931
967
|
};
|
|
932
968
|
/**
|
|
933
|
-
*
|
|
969
|
+
* Creates a NodeIterator object that you can use to traverse filtered lists of nodes or elements in a document.
|
|
934
970
|
*
|
|
935
|
-
* @param {
|
|
936
|
-
* @return {
|
|
971
|
+
* @param {Node} root The root element or node to start traversing on.
|
|
972
|
+
* @return {NodeIterator} The created NodeIterator
|
|
937
973
|
*/
|
|
938
974
|
|
|
939
975
|
|
|
940
|
-
const
|
|
976
|
+
const _createNodeIterator = function _createNodeIterator(root) {
|
|
941
977
|
return createNodeIterator.call(root.ownerDocument || root, root, // eslint-disable-next-line no-bitwise
|
|
942
|
-
NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_TEXT, null
|
|
978
|
+
NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_TEXT, null);
|
|
943
979
|
};
|
|
944
980
|
/**
|
|
945
981
|
* _isClobbered
|
|
@@ -953,15 +989,15 @@ function createDOMPurify() {
|
|
|
953
989
|
return elm instanceof HTMLFormElement && (typeof elm.nodeName !== 'string' || typeof elm.textContent !== 'string' || typeof elm.removeChild !== 'function' || !(elm.attributes instanceof NamedNodeMap) || typeof elm.removeAttribute !== 'function' || typeof elm.setAttribute !== 'function' || typeof elm.namespaceURI !== 'string' || typeof elm.insertBefore !== 'function' || typeof elm.hasChildNodes !== 'function');
|
|
954
990
|
};
|
|
955
991
|
/**
|
|
956
|
-
*
|
|
992
|
+
* Checks whether the given object is a DOM node.
|
|
957
993
|
*
|
|
958
|
-
* @param {Node}
|
|
994
|
+
* @param {Node} object object to check whether it's a DOM node
|
|
959
995
|
* @return {Boolean} true is object is a DOM node
|
|
960
996
|
*/
|
|
961
997
|
|
|
962
998
|
|
|
963
999
|
const _isNode = function _isNode(object) {
|
|
964
|
-
return typeof Node === '
|
|
1000
|
+
return typeof Node === 'function' && object instanceof Node;
|
|
965
1001
|
};
|
|
966
1002
|
/**
|
|
967
1003
|
* _executeHook
|
|
@@ -995,7 +1031,7 @@ function createDOMPurify() {
|
|
|
995
1031
|
|
|
996
1032
|
|
|
997
1033
|
const _sanitizeElements = function _sanitizeElements(currentNode) {
|
|
998
|
-
let content;
|
|
1034
|
+
let content = null;
|
|
999
1035
|
/* Execute a hook if present */
|
|
1000
1036
|
|
|
1001
1037
|
_executeHook('beforeSanitizeElements', currentNode, null);
|
|
@@ -1020,7 +1056,7 @@ function createDOMPurify() {
|
|
|
1020
1056
|
/* Detect mXSS attempts abusing namespace confusion */
|
|
1021
1057
|
|
|
1022
1058
|
|
|
1023
|
-
if (currentNode.hasChildNodes() && !_isNode(currentNode.firstElementChild) &&
|
|
1059
|
+
if (currentNode.hasChildNodes() && !_isNode(currentNode.firstElementChild) && regExpTest(/<[/\w]/g, currentNode.innerHTML) && regExpTest(/<[/\w]/g, currentNode.textContent)) {
|
|
1024
1060
|
_forceRemove(currentNode);
|
|
1025
1061
|
|
|
1026
1062
|
return true;
|
|
@@ -1030,9 +1066,14 @@ function createDOMPurify() {
|
|
|
1030
1066
|
|
|
1031
1067
|
if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) {
|
|
1032
1068
|
/* Check if we have a custom element to handle */
|
|
1033
|
-
if (!FORBID_TAGS[tagName] &&
|
|
1034
|
-
if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, tagName))
|
|
1035
|
-
|
|
1069
|
+
if (!FORBID_TAGS[tagName] && _isBasicCustomElement(tagName)) {
|
|
1070
|
+
if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, tagName)) {
|
|
1071
|
+
return false;
|
|
1072
|
+
}
|
|
1073
|
+
|
|
1074
|
+
if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(tagName)) {
|
|
1075
|
+
return false;
|
|
1076
|
+
}
|
|
1036
1077
|
}
|
|
1037
1078
|
/* Keep content except for bad-listed elements */
|
|
1038
1079
|
|
|
@@ -1076,9 +1117,9 @@ function createDOMPurify() {
|
|
|
1076
1117
|
if (SAFE_FOR_TEMPLATES && currentNode.nodeType === 3) {
|
|
1077
1118
|
/* Get the element's text content */
|
|
1078
1119
|
content = currentNode.textContent;
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1120
|
+
arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], expr => {
|
|
1121
|
+
content = stringReplace(content, expr, ' ');
|
|
1122
|
+
});
|
|
1082
1123
|
|
|
1083
1124
|
if (currentNode.textContent !== content) {
|
|
1084
1125
|
arrayPush(DOMPurify.removed, {
|
|
@@ -1120,7 +1161,7 @@ function createDOMPurify() {
|
|
|
1120
1161
|
if ( // First condition does a very basic check if a) it's basically a valid custom element tagname AND
|
|
1121
1162
|
// b) if the tagName passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck
|
|
1122
1163
|
// and c) if the attribute name passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.attributeNameCheck
|
|
1123
|
-
|
|
1164
|
+
_isBasicCustomElement(lcTag) && (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, lcTag) || CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(lcTag)) && (CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.attributeNameCheck, lcName) || CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.attributeNameCheck(lcName)) || // Alternative, second condition checks if it's an `is`-attribute, AND
|
|
1124
1165
|
// the value passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck
|
|
1125
1166
|
lcName === 'is' && CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements && (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, value) || CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(value))) ; else {
|
|
1126
1167
|
return false;
|
|
@@ -1134,14 +1175,16 @@ function createDOMPurify() {
|
|
|
1134
1175
|
return true;
|
|
1135
1176
|
};
|
|
1136
1177
|
/**
|
|
1137
|
-
*
|
|
1178
|
+
* _isBasicCustomElement
|
|
1138
1179
|
* checks if at least one dash is included in tagName, and it's not the first char
|
|
1139
1180
|
* for more sophisticated checking see https://github.com/sindresorhus/validate-element-name
|
|
1181
|
+
*
|
|
1140
1182
|
* @param {string} tagName name of the tag of the node to sanitize
|
|
1183
|
+
* @returns {boolean} Returns true if the tag name meets the basic criteria for a custom element, otherwise false.
|
|
1141
1184
|
*/
|
|
1142
1185
|
|
|
1143
1186
|
|
|
1144
|
-
const
|
|
1187
|
+
const _isBasicCustomElement = function _isBasicCustomElement(tagName) {
|
|
1145
1188
|
return tagName.indexOf('-') > 0;
|
|
1146
1189
|
};
|
|
1147
1190
|
/**
|
|
@@ -1157,12 +1200,7 @@ function createDOMPurify() {
|
|
|
1157
1200
|
|
|
1158
1201
|
|
|
1159
1202
|
const _sanitizeAttributes = function _sanitizeAttributes(currentNode) {
|
|
1160
|
-
let attr;
|
|
1161
|
-
let value;
|
|
1162
|
-
let lcName;
|
|
1163
|
-
let l;
|
|
1164
1203
|
/* Execute a hook if present */
|
|
1165
|
-
|
|
1166
1204
|
_executeHook('beforeSanitizeAttributes', currentNode, null);
|
|
1167
1205
|
|
|
1168
1206
|
const {
|
|
@@ -1180,17 +1218,18 @@ function createDOMPurify() {
|
|
|
1180
1218
|
keepAttr: true,
|
|
1181
1219
|
allowedAttributes: ALLOWED_ATTR
|
|
1182
1220
|
};
|
|
1183
|
-
l = attributes.length;
|
|
1221
|
+
let l = attributes.length;
|
|
1184
1222
|
/* Go backwards over all attributes; safely remove bad ones */
|
|
1185
1223
|
|
|
1186
1224
|
while (l--) {
|
|
1187
|
-
attr = attributes[l];
|
|
1225
|
+
const attr = attributes[l];
|
|
1188
1226
|
const {
|
|
1189
1227
|
name,
|
|
1190
|
-
namespaceURI
|
|
1228
|
+
namespaceURI,
|
|
1229
|
+
value: attrValue
|
|
1191
1230
|
} = attr;
|
|
1192
|
-
|
|
1193
|
-
|
|
1231
|
+
const lcName = transformCaseFunc(name);
|
|
1232
|
+
let value = name === 'value' ? attrValue : stringTrim(attrValue);
|
|
1194
1233
|
/* Execute a hook if present */
|
|
1195
1234
|
|
|
1196
1235
|
hookEvent.attrName = lcName;
|
|
@@ -1228,9 +1267,9 @@ function createDOMPurify() {
|
|
|
1228
1267
|
|
|
1229
1268
|
|
|
1230
1269
|
if (SAFE_FOR_TEMPLATES) {
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1270
|
+
arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], expr => {
|
|
1271
|
+
value = stringReplace(value, expr, ' ');
|
|
1272
|
+
});
|
|
1234
1273
|
}
|
|
1235
1274
|
/* Is `value` valid for this attribute? */
|
|
1236
1275
|
|
|
@@ -1299,9 +1338,9 @@ function createDOMPurify() {
|
|
|
1299
1338
|
|
|
1300
1339
|
|
|
1301
1340
|
const _sanitizeShadowDOM = function _sanitizeShadowDOM(fragment) {
|
|
1302
|
-
let shadowNode;
|
|
1341
|
+
let shadowNode = null;
|
|
1303
1342
|
|
|
1304
|
-
const shadowIterator =
|
|
1343
|
+
const shadowIterator = _createNodeIterator(fragment);
|
|
1305
1344
|
/* Execute a hook if present */
|
|
1306
1345
|
|
|
1307
1346
|
|
|
@@ -1337,17 +1376,17 @@ function createDOMPurify() {
|
|
|
1337
1376
|
* Public method providing core sanitation functionality
|
|
1338
1377
|
*
|
|
1339
1378
|
* @param {String|Node} dirty string or DOM node
|
|
1340
|
-
* @param {Object}
|
|
1379
|
+
* @param {Object} cfg object
|
|
1341
1380
|
*/
|
|
1342
1381
|
// eslint-disable-next-line complexity
|
|
1343
1382
|
|
|
1344
1383
|
|
|
1345
1384
|
DOMPurify.sanitize = function (dirty) {
|
|
1346
1385
|
let cfg = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
1347
|
-
let body;
|
|
1348
|
-
let importedNode;
|
|
1349
|
-
let currentNode;
|
|
1350
|
-
let returnNode;
|
|
1386
|
+
let body = null;
|
|
1387
|
+
let importedNode = null;
|
|
1388
|
+
let currentNode = null;
|
|
1389
|
+
let returnNode = null;
|
|
1351
1390
|
/* Make sure we have a string to sanitize.
|
|
1352
1391
|
DO NOT return early, as this will return the wrong type if
|
|
1353
1392
|
the user has requested a DOM object rather than a string */
|
|
@@ -1442,7 +1481,7 @@ function createDOMPurify() {
|
|
|
1442
1481
|
/* Get node iterator */
|
|
1443
1482
|
|
|
1444
1483
|
|
|
1445
|
-
const nodeIterator =
|
|
1484
|
+
const nodeIterator = _createNodeIterator(IN_PLACE ? dirty : body);
|
|
1446
1485
|
/* Now start iterating over the created document */
|
|
1447
1486
|
|
|
1448
1487
|
|
|
@@ -1507,9 +1546,9 @@ function createDOMPurify() {
|
|
|
1507
1546
|
|
|
1508
1547
|
|
|
1509
1548
|
if (SAFE_FOR_TEMPLATES) {
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1549
|
+
arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], expr => {
|
|
1550
|
+
serializedHTML = stringReplace(serializedHTML, expr, ' ');
|
|
1551
|
+
});
|
|
1513
1552
|
}
|
|
1514
1553
|
|
|
1515
1554
|
return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML(serializedHTML) : serializedHTML;
|
|
@@ -1522,7 +1561,9 @@ function createDOMPurify() {
|
|
|
1522
1561
|
*/
|
|
1523
1562
|
|
|
1524
1563
|
|
|
1525
|
-
DOMPurify.setConfig = function (
|
|
1564
|
+
DOMPurify.setConfig = function () {
|
|
1565
|
+
let cfg = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
1566
|
+
|
|
1526
1567
|
_parseConfig(cfg);
|
|
1527
1568
|
|
|
1528
1569
|
SET_CONFIG = true;
|
|
@@ -1543,9 +1584,9 @@ function createDOMPurify() {
|
|
|
1543
1584
|
* Uses last set config, if any. Otherwise, uses config defaults.
|
|
1544
1585
|
* isValidAttribute
|
|
1545
1586
|
*
|
|
1546
|
-
* @param {
|
|
1547
|
-
* @param {
|
|
1548
|
-
* @param {
|
|
1587
|
+
* @param {String} tag Tag name of containing element.
|
|
1588
|
+
* @param {String} attr Attribute name.
|
|
1589
|
+
* @param {String} value Attribute value.
|
|
1549
1590
|
* @return {Boolean} Returns true if `value` is valid. Otherwise, returns false.
|
|
1550
1591
|
*/
|
|
1551
1592
|
|
|
@@ -1608,7 +1649,6 @@ function createDOMPurify() {
|
|
|
1608
1649
|
/**
|
|
1609
1650
|
* RemoveAllHooks
|
|
1610
1651
|
* Public method to remove all DOMPurify hooks
|
|
1611
|
-
*
|
|
1612
1652
|
*/
|
|
1613
1653
|
|
|
1614
1654
|
|