dompurify 3.1.4 → 3.1.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 +11 -2
- package/dist/purify.cjs.js +15 -73
- package/dist/purify.cjs.js.map +1 -1
- package/dist/purify.es.mjs +15 -73
- package/dist/purify.es.mjs.map +1 -1
- package/dist/purify.js +15 -73
- 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.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! @license DOMPurify 3.1.
|
|
1
|
+
/*! @license DOMPurify 3.1.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.1.6/LICENSE */
|
|
2
2
|
|
|
3
3
|
const {
|
|
4
4
|
entries,
|
|
@@ -48,10 +48,6 @@ const stringTrim = unapply(String.prototype.trim);
|
|
|
48
48
|
const objectHasOwnProperty = unapply(Object.prototype.hasOwnProperty);
|
|
49
49
|
const regExpTest = unapply(RegExp.prototype.test);
|
|
50
50
|
const typeErrorCreate = unconstruct(TypeError);
|
|
51
|
-
function numberIsNaN(x) {
|
|
52
|
-
// eslint-disable-next-line unicorn/prefer-number-properties
|
|
53
|
-
return typeof x === 'number' && isNaN(x);
|
|
54
|
-
}
|
|
55
51
|
|
|
56
52
|
/**
|
|
57
53
|
* Creates a new function that calls the given function with a specified thisArg and arguments.
|
|
@@ -213,11 +209,9 @@ const DATA_ATTR = seal(/^data-[\-\w.\u00B7-\uFFFF]/); // eslint-disable-line no-
|
|
|
213
209
|
const ARIA_ATTR = seal(/^aria-[\-\w]+$/); // eslint-disable-line no-useless-escape
|
|
214
210
|
const IS_ALLOWED_URI = seal(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i // eslint-disable-line no-useless-escape
|
|
215
211
|
);
|
|
216
|
-
|
|
217
212
|
const IS_SCRIPT_OR_DATA = seal(/^(?:\w+script|data):/i);
|
|
218
213
|
const ATTR_WHITESPACE = seal(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g // eslint-disable-line no-control-regex
|
|
219
214
|
);
|
|
220
|
-
|
|
221
215
|
const DOCTYPE_NAME = seal(/^html$/i);
|
|
222
216
|
const CUSTOM_ELEMENT = seal(/^[a-z][.\w]*(-[.\w]+)+$/i);
|
|
223
217
|
|
|
@@ -252,7 +246,6 @@ const NODE_TYPE = {
|
|
|
252
246
|
documentFragment: 11,
|
|
253
247
|
notation: 12 // Deprecated
|
|
254
248
|
};
|
|
255
|
-
|
|
256
249
|
const getGlobal = function getGlobal() {
|
|
257
250
|
return typeof window === 'undefined' ? null : window;
|
|
258
251
|
};
|
|
@@ -304,7 +297,7 @@ function createDOMPurify() {
|
|
|
304
297
|
* Version label, exposed for easier checks
|
|
305
298
|
* if DOMPurify is up to date or not
|
|
306
299
|
*/
|
|
307
|
-
DOMPurify.version = '3.1.
|
|
300
|
+
DOMPurify.version = '3.1.6';
|
|
308
301
|
|
|
309
302
|
/**
|
|
310
303
|
* Array of elements that DOMPurify removed during sanitation.
|
|
@@ -335,6 +328,7 @@ function createDOMPurify() {
|
|
|
335
328
|
} = window;
|
|
336
329
|
const ElementPrototype = Element.prototype;
|
|
337
330
|
const cloneNode = lookupGetter(ElementPrototype, 'cloneNode');
|
|
331
|
+
const remove = lookupGetter(ElementPrototype, 'remove');
|
|
338
332
|
const getNextSibling = lookupGetter(ElementPrototype, 'nextSibling');
|
|
339
333
|
const getChildNodes = lookupGetter(ElementPrototype, 'childNodes');
|
|
340
334
|
const getParentNode = lookupGetter(ElementPrototype, 'parentNode');
|
|
@@ -537,9 +531,6 @@ function createDOMPurify() {
|
|
|
537
531
|
/* Keep a reference to config to pass to hooks */
|
|
538
532
|
let CONFIG = null;
|
|
539
533
|
|
|
540
|
-
/* Specify the maximum element nesting depth to prevent mXSS */
|
|
541
|
-
const MAX_NESTING_DEPTH = 255;
|
|
542
|
-
|
|
543
534
|
/* Ideally, do not touch anything below this line */
|
|
544
535
|
/* ______________________________________________ */
|
|
545
536
|
|
|
@@ -838,9 +829,9 @@ function createDOMPurify() {
|
|
|
838
829
|
});
|
|
839
830
|
try {
|
|
840
831
|
// eslint-disable-next-line unicorn/prefer-dom-node-remove
|
|
841
|
-
node.
|
|
832
|
+
getParentNode(node).removeChild(node);
|
|
842
833
|
} catch (_) {
|
|
843
|
-
|
|
834
|
+
remove(node);
|
|
844
835
|
}
|
|
845
836
|
};
|
|
846
837
|
|
|
@@ -950,11 +941,7 @@ function createDOMPurify() {
|
|
|
950
941
|
* @return {Boolean} true if clobbered, false if safe
|
|
951
942
|
*/
|
|
952
943
|
const _isClobbered = function _isClobbered(elm) {
|
|
953
|
-
return elm instanceof HTMLFormElement && (
|
|
954
|
-
// eslint-disable-next-line unicorn/no-typeof-undefined
|
|
955
|
-
typeof elm.__depth !== 'undefined' && typeof elm.__depth !== 'number' ||
|
|
956
|
-
// eslint-disable-next-line unicorn/no-typeof-undefined
|
|
957
|
-
typeof elm.__removalCount !== 'undefined' && typeof elm.__removalCount !== 'number' || 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');
|
|
944
|
+
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');
|
|
958
945
|
};
|
|
959
946
|
|
|
960
947
|
/**
|
|
@@ -1021,7 +1008,7 @@ function createDOMPurify() {
|
|
|
1021
1008
|
return true;
|
|
1022
1009
|
}
|
|
1023
1010
|
|
|
1024
|
-
/* Remove any
|
|
1011
|
+
/* Remove any occurrence of processing instructions */
|
|
1025
1012
|
if (currentNode.nodeType === NODE_TYPE.progressingInstruction) {
|
|
1026
1013
|
_forceRemove(currentNode);
|
|
1027
1014
|
return true;
|
|
@@ -1105,7 +1092,7 @@ function createDOMPurify() {
|
|
|
1105
1092
|
// eslint-disable-next-line complexity
|
|
1106
1093
|
const _isValidAttribute = function _isValidAttribute(lcTag, lcName, value) {
|
|
1107
1094
|
/* Make sure attribute cannot clobber */
|
|
1108
|
-
if (SANITIZE_DOM && (lcName === 'id' || lcName === 'name') && (value in document || value in formElement
|
|
1095
|
+
if (SANITIZE_DOM && (lcName === 'id' || lcName === 'name') && (value in document || value in formElement)) {
|
|
1109
1096
|
return false;
|
|
1110
1097
|
}
|
|
1111
1098
|
|
|
@@ -1190,6 +1177,13 @@ function createDOMPurify() {
|
|
|
1190
1177
|
hookEvent.forceKeepAttr = undefined; // Allows developers to see this is a property they can set
|
|
1191
1178
|
_executeHook('uponSanitizeAttribute', currentNode, hookEvent);
|
|
1192
1179
|
value = hookEvent.attrValue;
|
|
1180
|
+
|
|
1181
|
+
/* Work around a security issue with comments inside attributes */
|
|
1182
|
+
if (SAFE_FOR_XML && regExpTest(/((--!?|])>)|<\/(style|title)/i, value)) {
|
|
1183
|
+
_removeAttribute(name, currentNode);
|
|
1184
|
+
continue;
|
|
1185
|
+
}
|
|
1186
|
+
|
|
1193
1187
|
/* Did the hooks approve of the attribute? */
|
|
1194
1188
|
if (hookEvent.forceKeepAttr) {
|
|
1195
1189
|
continue;
|
|
@@ -1209,12 +1203,6 @@ function createDOMPurify() {
|
|
|
1209
1203
|
continue;
|
|
1210
1204
|
}
|
|
1211
1205
|
|
|
1212
|
-
/* Work around a security issue with comments inside attributes */
|
|
1213
|
-
if (SAFE_FOR_XML && regExpTest(/((--!?|])>)|<\/(style|title)/i, value)) {
|
|
1214
|
-
_removeAttribute(name, currentNode);
|
|
1215
|
-
continue;
|
|
1216
|
-
}
|
|
1217
|
-
|
|
1218
1206
|
/* Sanitize attribute content to be template-safe */
|
|
1219
1207
|
if (SAFE_FOR_TEMPLATES) {
|
|
1220
1208
|
arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], expr => {
|
|
@@ -1296,32 +1284,9 @@ function createDOMPurify() {
|
|
|
1296
1284
|
if (_sanitizeElements(shadowNode)) {
|
|
1297
1285
|
continue;
|
|
1298
1286
|
}
|
|
1299
|
-
const parentNode = getParentNode(shadowNode);
|
|
1300
|
-
|
|
1301
|
-
/* Set the nesting depth of an element */
|
|
1302
|
-
if (shadowNode.nodeType === NODE_TYPE.element) {
|
|
1303
|
-
if (parentNode && parentNode.__depth) {
|
|
1304
|
-
/*
|
|
1305
|
-
We want the depth of the node in the original tree, which can
|
|
1306
|
-
change when it's removed from its parent.
|
|
1307
|
-
*/
|
|
1308
|
-
shadowNode.__depth = (shadowNode.__removalCount || 0) + parentNode.__depth + 1;
|
|
1309
|
-
} else {
|
|
1310
|
-
shadowNode.__depth = 1;
|
|
1311
|
-
}
|
|
1312
|
-
}
|
|
1313
|
-
|
|
1314
|
-
/*
|
|
1315
|
-
* Remove an element if nested too deeply to avoid mXSS
|
|
1316
|
-
* or if the __depth might have been tampered with
|
|
1317
|
-
*/
|
|
1318
|
-
if (shadowNode.__depth >= MAX_NESTING_DEPTH || shadowNode.__depth < 0 || numberIsNaN(shadowNode.__depth)) {
|
|
1319
|
-
_forceRemove(shadowNode);
|
|
1320
|
-
}
|
|
1321
1287
|
|
|
1322
1288
|
/* Deep shadow DOM detected */
|
|
1323
1289
|
if (shadowNode.content instanceof DocumentFragment) {
|
|
1324
|
-
shadowNode.content.__depth = shadowNode.__depth;
|
|
1325
1290
|
_sanitizeShadowDOM(shadowNode.content);
|
|
1326
1291
|
}
|
|
1327
1292
|
|
|
@@ -1437,32 +1402,9 @@ function createDOMPurify() {
|
|
|
1437
1402
|
if (_sanitizeElements(currentNode)) {
|
|
1438
1403
|
continue;
|
|
1439
1404
|
}
|
|
1440
|
-
const parentNode = getParentNode(currentNode);
|
|
1441
|
-
|
|
1442
|
-
/* Set the nesting depth of an element */
|
|
1443
|
-
if (currentNode.nodeType === NODE_TYPE.element) {
|
|
1444
|
-
if (parentNode && parentNode.__depth) {
|
|
1445
|
-
/*
|
|
1446
|
-
We want the depth of the node in the original tree, which can
|
|
1447
|
-
change when it's removed from its parent.
|
|
1448
|
-
*/
|
|
1449
|
-
currentNode.__depth = (currentNode.__removalCount || 0) + parentNode.__depth + 1;
|
|
1450
|
-
} else {
|
|
1451
|
-
currentNode.__depth = 1;
|
|
1452
|
-
}
|
|
1453
|
-
}
|
|
1454
|
-
|
|
1455
|
-
/*
|
|
1456
|
-
* Remove an element if nested too deeply to avoid mXSS
|
|
1457
|
-
* or if the __depth might have been tampered with
|
|
1458
|
-
*/
|
|
1459
|
-
if (currentNode.__depth >= MAX_NESTING_DEPTH || currentNode.__depth < 0 || numberIsNaN(currentNode.__depth)) {
|
|
1460
|
-
_forceRemove(currentNode);
|
|
1461
|
-
}
|
|
1462
1405
|
|
|
1463
1406
|
/* Shadow DOM detected, sanitize it */
|
|
1464
1407
|
if (currentNode.content instanceof DocumentFragment) {
|
|
1465
|
-
currentNode.content.__depth = currentNode.__depth;
|
|
1466
1408
|
_sanitizeShadowDOM(currentNode.content);
|
|
1467
1409
|
}
|
|
1468
1410
|
|