dompurify 3.1.3 → 3.1.5

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/dist/purify.js CHANGED
@@ -1,4 +1,4 @@
1
- /*! @license DOMPurify 3.1.3 | (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.3/LICENSE */
1
+ /*! @license DOMPurify 3.1.5 | (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.5/LICENSE */
2
2
 
3
3
  (function (global, factory) {
4
4
  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
@@ -54,7 +54,6 @@
54
54
  const objectHasOwnProperty = unapply(Object.prototype.hasOwnProperty);
55
55
  const regExpTest = unapply(RegExp.prototype.test);
56
56
  const typeErrorCreate = unconstruct(TypeError);
57
- const numberIsNaN = unapply(Number.isNaN);
58
57
 
59
58
  /**
60
59
  * Creates a new function that calls the given function with a specified thisArg and arguments.
@@ -203,7 +202,7 @@
203
202
  const mathMlDisallowed = freeze(['maction', 'maligngroup', 'malignmark', 'mlongdiv', 'mscarries', 'mscarry', 'msgroup', 'mstack', 'msline', 'msrow', 'semantics', 'annotation', 'annotation-xml', 'mprescripts', 'none']);
204
203
  const text = freeze(['#text']);
205
204
 
206
- const html = freeze(['accept', 'action', 'align', 'alt', 'autocapitalize', 'autocomplete', 'autopictureinpicture', 'autoplay', 'background', 'bgcolor', 'border', 'capture', 'cellpadding', 'cellspacing', 'checked', 'cite', 'class', 'clear', 'color', 'cols', 'colspan', 'controls', 'controlslist', 'coords', 'crossorigin', 'datetime', 'decoding', 'default', 'dir', 'disabled', 'disablepictureinpicture', 'disableremoteplayback', 'download', 'draggable', 'enctype', 'enterkeyhint', 'face', 'for', 'headers', 'height', 'hidden', 'high', 'href', 'hreflang', 'id', 'inputmode', 'integrity', 'ismap', 'kind', 'label', 'lang', 'list', 'loading', 'loop', 'low', 'max', 'maxlength', 'media', 'method', 'min', 'minlength', 'multiple', 'muted', 'name', 'nonce', 'noshade', 'novalidate', 'nowrap', 'open', 'optimum', 'pattern', 'placeholder', 'playsinline', 'poster', 'preload', 'pubdate', 'radiogroup', 'readonly', 'rel', 'required', 'rev', 'reversed', 'role', 'rows', 'rowspan', 'spellcheck', 'scope', 'selected', 'shape', 'size', 'sizes', 'span', 'srclang', 'start', 'src', 'srcset', 'step', 'style', 'summary', 'tabindex', 'title', 'translate', 'type', 'usemap', 'valign', 'value', 'width', 'wrap', 'xmlns', 'slot']);
205
+ const html = freeze(['accept', 'action', 'align', 'alt', 'autocapitalize', 'autocomplete', 'autopictureinpicture', 'autoplay', 'background', 'bgcolor', 'border', 'capture', 'cellpadding', 'cellspacing', 'checked', 'cite', 'class', 'clear', 'color', 'cols', 'colspan', 'controls', 'controlslist', 'coords', 'crossorigin', 'datetime', 'decoding', 'default', 'dir', 'disabled', 'disablepictureinpicture', 'disableremoteplayback', 'download', 'draggable', 'enctype', 'enterkeyhint', 'face', 'for', 'headers', 'height', 'hidden', 'high', 'href', 'hreflang', 'id', 'inputmode', 'integrity', 'ismap', 'kind', 'label', 'lang', 'list', 'loading', 'loop', 'low', 'max', 'maxlength', 'media', 'method', 'min', 'minlength', 'multiple', 'muted', 'name', 'nonce', 'noshade', 'novalidate', 'nowrap', 'open', 'optimum', 'pattern', 'placeholder', 'playsinline', 'popover', 'popovertarget', 'popovertargetaction', 'poster', 'preload', 'pubdate', 'radiogroup', 'readonly', 'rel', 'required', 'rev', 'reversed', 'role', 'rows', 'rowspan', 'spellcheck', 'scope', 'selected', 'shape', 'size', 'sizes', 'span', 'srclang', 'start', 'src', 'srcset', 'step', 'style', 'summary', 'tabindex', 'title', 'translate', 'type', 'usemap', 'valign', 'value', 'width', 'wrap', 'xmlns', 'slot']);
207
206
  const svg = freeze(['accent-height', 'accumulate', 'additive', 'alignment-baseline', 'ascent', 'attributename', 'attributetype', 'azimuth', 'basefrequency', 'baseline-shift', 'begin', 'bias', 'by', 'class', 'clip', 'clippathunits', 'clip-path', 'clip-rule', 'color', 'color-interpolation', 'color-interpolation-filters', 'color-profile', 'color-rendering', 'cx', 'cy', 'd', 'dx', 'dy', 'diffuseconstant', 'direction', 'display', 'divisor', 'dur', 'edgemode', 'elevation', 'end', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'filterunits', 'flood-color', 'flood-opacity', 'font-family', 'font-size', 'font-size-adjust', 'font-stretch', 'font-style', 'font-variant', 'font-weight', 'fx', 'fy', 'g1', 'g2', 'glyph-name', 'glyphref', 'gradientunits', 'gradienttransform', 'height', 'href', 'id', 'image-rendering', 'in', 'in2', 'k', 'k1', 'k2', 'k3', 'k4', 'kerning', 'keypoints', 'keysplines', 'keytimes', 'lang', 'lengthadjust', 'letter-spacing', 'kernelmatrix', 'kernelunitlength', 'lighting-color', 'local', 'marker-end', 'marker-mid', 'marker-start', 'markerheight', 'markerunits', 'markerwidth', 'maskcontentunits', 'maskunits', 'max', 'mask', 'media', 'method', 'mode', 'min', 'name', 'numoctaves', 'offset', 'operator', 'opacity', 'order', 'orient', 'orientation', 'origin', 'overflow', 'paint-order', 'path', 'pathlength', 'patterncontentunits', 'patterntransform', 'patternunits', 'points', 'preservealpha', 'preserveaspectratio', 'primitiveunits', 'r', 'rx', 'ry', 'radius', 'refx', 'refy', 'repeatcount', 'repeatdur', 'restart', 'result', 'rotate', 'scale', 'seed', 'shape-rendering', 'specularconstant', 'specularexponent', 'spreadmethod', 'startoffset', 'stddeviation', 'stitchtiles', 'stop-color', 'stop-opacity', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke', 'stroke-width', 'style', 'surfacescale', 'systemlanguage', 'tabindex', 'targetx', 'targety', 'transform', 'transform-origin', 'text-anchor', 'text-decoration', 'text-rendering', 'textlength', 'type', 'u1', 'u2', 'unicode', 'values', 'viewbox', 'visibility', 'version', 'vert-adv-y', 'vert-origin-x', 'vert-origin-y', 'width', 'word-spacing', 'wrap', 'writing-mode', 'xchannelselector', 'ychannelselector', 'x', 'x1', 'x2', 'xmlns', 'y', 'y1', 'y2', 'z', 'zoomandpan']);
208
207
  const mathMl = freeze(['accent', 'accentunder', 'align', 'bevelled', 'close', 'columnsalign', 'columnlines', 'columnspan', 'denomalign', 'depth', 'dir', 'display', 'displaystyle', 'encoding', 'fence', 'frame', 'height', 'href', 'id', 'largeop', 'length', 'linethickness', 'lspace', 'lquote', 'mathbackground', 'mathcolor', 'mathsize', 'mathvariant', 'maxsize', 'minsize', 'movablelimits', 'notation', 'numalign', 'open', 'rowalign', 'rowlines', 'rowspacing', 'rowspan', 'rspace', 'rquote', 'scriptlevel', 'scriptminsize', 'scriptsizemultiplier', 'selection', 'separator', 'separators', 'stretchy', 'subscriptshift', 'supscriptshift', 'symmetric', 'voffset', 'width', 'xmlns']);
209
208
  const xml = freeze(['xlink:href', 'xml:id', 'xlink:title', 'xml:space', 'xmlns:xlink']);
@@ -307,7 +306,7 @@
307
306
  * Version label, exposed for easier checks
308
307
  * if DOMPurify is up to date or not
309
308
  */
310
- DOMPurify.version = '3.1.3';
309
+ DOMPurify.version = '3.1.5';
311
310
 
312
311
  /**
313
312
  * Array of elements that DOMPurify removed during sanitation.
@@ -540,9 +539,6 @@
540
539
  /* Keep a reference to config to pass to hooks */
541
540
  let CONFIG = null;
542
541
 
543
- /* Specify the maximum element nesting depth to prevent mXSS */
544
- const MAX_NESTING_DEPTH = 255;
545
-
546
542
  /* Ideally, do not touch anything below this line */
547
543
  /* ______________________________________________ */
548
544
 
@@ -953,11 +949,7 @@
953
949
  * @return {Boolean} true if clobbered, false if safe
954
950
  */
955
951
  const _isClobbered = function _isClobbered(elm) {
956
- return elm instanceof HTMLFormElement && (
957
- // eslint-disable-next-line unicorn/no-typeof-undefined
958
- typeof elm.__depth !== 'undefined' && typeof elm.__depth !== 'number' ||
959
- // eslint-disable-next-line unicorn/no-typeof-undefined
960
- 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');
952
+ 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');
961
953
  };
962
954
 
963
955
  /**
@@ -1108,7 +1100,7 @@
1108
1100
  // eslint-disable-next-line complexity
1109
1101
  const _isValidAttribute = function _isValidAttribute(lcTag, lcName, value) {
1110
1102
  /* Make sure attribute cannot clobber */
1111
- if (SANITIZE_DOM && (lcName === 'id' || lcName === 'name') && (value in document || value in formElement || value === '__depth' || value === '__removalCount')) {
1103
+ if (SANITIZE_DOM && (lcName === 'id' || lcName === 'name') && (value in document || value in formElement)) {
1112
1104
  return false;
1113
1105
  }
1114
1106
 
@@ -1299,32 +1291,9 @@
1299
1291
  if (_sanitizeElements(shadowNode)) {
1300
1292
  continue;
1301
1293
  }
1302
- const parentNode = getParentNode(shadowNode);
1303
-
1304
- /* Set the nesting depth of an element */
1305
- if (shadowNode.nodeType === NODE_TYPE.element) {
1306
- if (parentNode && parentNode.__depth) {
1307
- /*
1308
- We want the depth of the node in the original tree, which can
1309
- change when it's removed from its parent.
1310
- */
1311
- shadowNode.__depth = (shadowNode.__removalCount || 0) + parentNode.__depth + 1;
1312
- } else {
1313
- shadowNode.__depth = 1;
1314
- }
1315
- }
1316
-
1317
- /*
1318
- * Remove an element if nested too deeply to avoid mXSS
1319
- * or if the __depth might have been tampered with
1320
- */
1321
- if (shadowNode.__depth >= MAX_NESTING_DEPTH || shadowNode.__depth < 0 || numberIsNaN(shadowNode.__depth)) {
1322
- _forceRemove(shadowNode);
1323
- }
1324
1294
 
1325
1295
  /* Deep shadow DOM detected */
1326
1296
  if (shadowNode.content instanceof DocumentFragment) {
1327
- shadowNode.content.__depth = shadowNode.__depth;
1328
1297
  _sanitizeShadowDOM(shadowNode.content);
1329
1298
  }
1330
1299
 
@@ -1440,32 +1409,9 @@
1440
1409
  if (_sanitizeElements(currentNode)) {
1441
1410
  continue;
1442
1411
  }
1443
- const parentNode = getParentNode(currentNode);
1444
-
1445
- /* Set the nesting depth of an element */
1446
- if (currentNode.nodeType === NODE_TYPE.element) {
1447
- if (parentNode && parentNode.__depth) {
1448
- /*
1449
- We want the depth of the node in the original tree, which can
1450
- change when it's removed from its parent.
1451
- */
1452
- currentNode.__depth = (currentNode.__removalCount || 0) + parentNode.__depth + 1;
1453
- } else {
1454
- currentNode.__depth = 1;
1455
- }
1456
- }
1457
-
1458
- /*
1459
- * Remove an element if nested too deeply to avoid mXSS
1460
- * or if the __depth might have been tampered with
1461
- */
1462
- if (currentNode.__depth >= MAX_NESTING_DEPTH || currentNode.__depth < 0 || numberIsNaN(currentNode.__depth)) {
1463
- _forceRemove(currentNode);
1464
- }
1465
1412
 
1466
1413
  /* Shadow DOM detected, sanitize it */
1467
1414
  if (currentNode.content instanceof DocumentFragment) {
1468
- currentNode.content.__depth = currentNode.__depth;
1469
1415
  _sanitizeShadowDOM(currentNode.content);
1470
1416
  }
1471
1417