dompurify 2.2.5 → 2.2.9

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.es.js CHANGED
@@ -137,7 +137,12 @@ function lookupGetter(object, prop) {
137
137
  object = getPrototypeOf(object);
138
138
  }
139
139
 
140
- return null;
140
+ function fallbackValue(element) {
141
+ console.warn('fallback value for', element);
142
+ return null;
143
+ }
144
+
145
+ return fallbackValue;
141
146
  }
142
147
 
143
148
  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']);
@@ -161,7 +166,7 @@ var mathMlDisallowed = freeze(['maction', 'maligngroup', 'malignmark', 'mlongdiv
161
166
 
162
167
  var text = freeze(['#text']);
163
168
 
164
- var html$1 = 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', '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', 'xmlns']);
169
+ var html$1 = 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', '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', 'xmlns', 'slot']);
165
170
 
166
171
  var svg$1 = 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', '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']);
167
172
 
@@ -238,7 +243,7 @@ function createDOMPurify() {
238
243
  * Version label, exposed for easier checks
239
244
  * if DOMPurify is up to date or not
240
245
  */
241
- DOMPurify.version = '2.2.5';
246
+ DOMPurify.version = '2.2.9';
242
247
 
243
248
  /**
244
249
  * Array of elements that DOMPurify removed during sanitation.
@@ -296,7 +301,6 @@ function createDOMPurify() {
296
301
  var _document = document,
297
302
  implementation = _document.implementation,
298
303
  createNodeIterator = _document.createNodeIterator,
299
- getElementsByTagName = _document.getElementsByTagName,
300
304
  createDocumentFragment = _document.createDocumentFragment;
301
305
  var importNode = originalDocument.importNode;
302
306
 
@@ -311,7 +315,7 @@ function createDOMPurify() {
311
315
  /**
312
316
  * Expose whether this browser supports running the full DOMPurify.
313
317
  */
314
- DOMPurify.isSupported = implementation && typeof implementation.createHTMLDocument !== 'undefined' && documentMode !== 9;
318
+ DOMPurify.isSupported = typeof getParentNode === 'function' && implementation && typeof implementation.createHTMLDocument !== 'undefined' && documentMode !== 9;
315
319
 
316
320
  var MUSTACHE_EXPR$$1 = MUSTACHE_EXPR,
317
321
  ERB_EXPR$$1 = ERB_EXPR,
@@ -414,6 +418,13 @@ function createDOMPurify() {
414
418
  var URI_SAFE_ATTRIBUTES = null;
415
419
  var DEFAULT_URI_SAFE_ATTRIBUTES = addToSet({}, ['alt', 'class', 'for', 'id', 'label', 'name', 'pattern', 'placeholder', 'summary', 'title', 'value', 'style', 'xmlns']);
416
420
 
421
+ var MATHML_NAMESPACE = 'http://www.w3.org/1998/Math/MathML';
422
+ var SVG_NAMESPACE = 'http://www.w3.org/2000/svg';
423
+ var HTML_NAMESPACE = 'http://www.w3.org/1999/xhtml';
424
+ /* Document namespace */
425
+ var NAMESPACE = HTML_NAMESPACE;
426
+ var IS_EMPTY_INPUT = false;
427
+
417
428
  /* Keep a reference to config to pass to hooks */
418
429
  var CONFIG = null;
419
430
 
@@ -463,6 +474,7 @@ function createDOMPurify() {
463
474
  KEEP_CONTENT = cfg.KEEP_CONTENT !== false; // Default true
464
475
  IN_PLACE = cfg.IN_PLACE || false; // Default false
465
476
  IS_ALLOWED_URI$$1 = cfg.ALLOWED_URI_REGEXP || IS_ALLOWED_URI$$1;
477
+ NAMESPACE = cfg.NAMESPACE || HTML_NAMESPACE;
466
478
  if (SAFE_FOR_TEMPLATES) {
467
479
  ALLOW_DATA_ATTR = false;
468
480
  }
@@ -559,10 +571,6 @@ function createDOMPurify() {
559
571
  var ALL_MATHML_TAGS = addToSet({}, mathMl);
560
572
  addToSet(ALL_MATHML_TAGS, mathMlDisallowed);
561
573
 
562
- var MATHML_NAMESPACE = 'http://www.w3.org/1998/Math/MathML';
563
- var SVG_NAMESPACE = 'http://www.w3.org/2000/svg';
564
- var HTML_NAMESPACE = 'http://www.w3.org/1999/xhtml';
565
-
566
574
  /**
567
575
  *
568
576
  *
@@ -662,6 +670,7 @@ function createDOMPurify() {
662
670
  var _forceRemove = function _forceRemove(node) {
663
671
  arrayPush(DOMPurify.removed, { element: node });
664
672
  try {
673
+ // eslint-disable-next-line unicorn/prefer-dom-node-remove
665
674
  node.parentNode.removeChild(node);
666
675
  } catch (_) {
667
676
  try {
@@ -692,6 +701,19 @@ function createDOMPurify() {
692
701
  }
693
702
 
694
703
  node.removeAttribute(name);
704
+
705
+ // We void attribute values for unremovable "is"" attributes
706
+ if (name === 'is' && !ALLOWED_ATTR[name]) {
707
+ if (RETURN_DOM || RETURN_DOM_FRAGMENT) {
708
+ try {
709
+ _forceRemove(node);
710
+ } catch (_) {}
711
+ } else {
712
+ try {
713
+ node.setAttribute(name, '');
714
+ } catch (_) {}
715
+ }
716
+ }
695
717
  };
696
718
 
697
719
  /**
@@ -714,27 +736,34 @@ function createDOMPurify() {
714
736
  }
715
737
 
716
738
  var dirtyPayload = trustedTypesPolicy ? trustedTypesPolicy.createHTML(dirty) : dirty;
717
- /* Use the DOMParser API by default, fallback later if needs be */
718
- try {
719
- doc = new DOMParser().parseFromString(dirtyPayload, 'text/html');
720
- } catch (_) {}
739
+ /*
740
+ * Use the DOMParser API by default, fallback later if needs be
741
+ * DOMParser not work for svg when has multiple root element.
742
+ */
743
+ if (NAMESPACE === HTML_NAMESPACE) {
744
+ try {
745
+ doc = new DOMParser().parseFromString(dirtyPayload, 'text/html');
746
+ } catch (_) {}
747
+ }
721
748
 
722
749
  /* Use createHTMLDocument in case DOMParser is not available */
723
750
  if (!doc || !doc.documentElement) {
724
- doc = implementation.createHTMLDocument('');
725
- var _doc = doc,
726
- body = _doc.body;
727
-
728
- body.parentNode.removeChild(body.parentNode.firstElementChild);
729
- body.outerHTML = dirtyPayload;
751
+ doc = implementation.createDocument(NAMESPACE, 'template', null);
752
+ try {
753
+ doc.documentElement.innerHTML = IS_EMPTY_INPUT ? '' : dirtyPayload;
754
+ } catch (_) {
755
+ // Syntax error if dirtyPayload is invalid xml
756
+ }
730
757
  }
731
758
 
759
+ var body = doc.body || doc.documentElement;
760
+
732
761
  if (dirty && leadingWhitespace) {
733
- doc.body.insertBefore(document.createTextNode(leadingWhitespace), doc.body.childNodes[0] || null);
762
+ body.insertBefore(document.createTextNode(leadingWhitespace), body.childNodes[0] || null);
734
763
  }
735
764
 
736
765
  /* Work on whole document or just its body */
737
- return getElementsByTagName.call(doc, WHOLE_DOCUMENT ? 'html' : 'body')[0];
766
+ return WHOLE_DOCUMENT ? doc.documentElement : body;
738
767
  };
739
768
 
740
769
  /**
@@ -744,9 +773,7 @@ function createDOMPurify() {
744
773
  * @return {Iterator} iterator instance
745
774
  */
746
775
  var _createIterator = function _createIterator(root) {
747
- return createNodeIterator.call(root.ownerDocument || root, root, NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_TEXT, function () {
748
- return NodeFilter.FILTER_ACCEPT;
749
- }, false);
776
+ return createNodeIterator.call(root.ownerDocument || root, root, NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_TEXT, null, false);
750
777
  };
751
778
 
752
779
  /**
@@ -842,11 +869,15 @@ function createDOMPurify() {
842
869
  if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) {
843
870
  /* Keep content except for bad-listed elements */
844
871
  if (KEEP_CONTENT && !FORBID_CONTENTS[tagName]) {
845
- var parentNode = getParentNode(currentNode);
846
- var childNodes = getChildNodes(currentNode);
847
- var childCount = childNodes.length;
848
- for (var i = childCount - 1; i >= 0; --i) {
849
- parentNode.insertBefore(cloneNode(childNodes[i], true), getNextSibling(currentNode));
872
+ var parentNode = getParentNode(currentNode) || currentNode.parentNode;
873
+ var childNodes = getChildNodes(currentNode) || currentNode.childNodes;
874
+
875
+ if (childNodes && parentNode) {
876
+ var childCount = childNodes.length;
877
+
878
+ for (var i = childCount - 1; i >= 0; --i) {
879
+ parentNode.insertBefore(cloneNode(childNodes[i], true), getNextSibling(currentNode));
880
+ }
850
881
  }
851
882
  }
852
883
 
@@ -1063,7 +1094,8 @@ function createDOMPurify() {
1063
1094
  /* Make sure we have a string to sanitize.
1064
1095
  DO NOT return early, as this will return the wrong type if
1065
1096
  the user has requested a DOM object rather than a string */
1066
- if (!dirty) {
1097
+ IS_EMPTY_INPUT = !dirty;
1098
+ if (IS_EMPTY_INPUT) {
1067
1099
  dirty = '<!-->';
1068
1100
  }
1069
1101
 
@@ -1119,7 +1151,7 @@ function createDOMPurify() {
1119
1151
  } else if (importedNode.nodeName === 'HTML') {
1120
1152
  body = importedNode;
1121
1153
  } else {
1122
- // eslint-disable-next-line unicorn/prefer-node-append
1154
+ // eslint-disable-next-line unicorn/prefer-dom-node-append
1123
1155
  body.appendChild(importedNode);
1124
1156
  }
1125
1157
  } else {
@@ -1183,7 +1215,7 @@ function createDOMPurify() {
1183
1215
  returnNode = createDocumentFragment.call(body.ownerDocument);
1184
1216
 
1185
1217
  while (body.firstChild) {
1186
- // eslint-disable-next-line unicorn/prefer-node-append
1218
+ // eslint-disable-next-line unicorn/prefer-dom-node-append
1187
1219
  returnNode.appendChild(body.firstChild);
1188
1220
  }
1189
1221
  } else {