dompurify 2.3.2 → 2.3.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 +73 -31
- package/dist/purify.cjs.js +102 -37
- package/dist/purify.cjs.js.map +1 -1
- package/dist/purify.es.js +102 -37
- package/dist/purify.es.js.map +1 -1
- package/dist/purify.js +102 -37
- 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 -15
package/dist/purify.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! @license DOMPurify 2.3.
|
|
1
|
+
/*! @license DOMPurify 2.3.6 | (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.6/LICENSE */
|
|
2
2
|
|
|
3
3
|
(function (global, factory) {
|
|
4
4
|
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
|
|
@@ -156,13 +156,13 @@
|
|
|
156
156
|
// SVG
|
|
157
157
|
var svg = freeze(['svg', 'a', 'altglyph', 'altglyphdef', 'altglyphitem', 'animatecolor', 'animatemotion', 'animatetransform', 'circle', 'clippath', 'defs', 'desc', 'ellipse', 'filter', 'font', 'g', 'glyph', 'glyphref', 'hkern', 'image', 'line', 'lineargradient', 'marker', 'mask', 'metadata', 'mpath', 'path', 'pattern', 'polygon', 'polyline', 'radialgradient', 'rect', 'stop', 'style', 'switch', 'symbol', 'text', 'textpath', 'title', 'tref', 'tspan', 'view', 'vkern']);
|
|
158
158
|
|
|
159
|
-
var svgFilters = freeze(['feBlend', 'feColorMatrix', 'feComponentTransfer', 'feComposite', 'feConvolveMatrix', 'feDiffuseLighting', 'feDisplacementMap', 'feDistantLight', 'feFlood', 'feFuncA', 'feFuncB', 'feFuncG', 'feFuncR', 'feGaussianBlur', 'feMerge', 'feMergeNode', 'feMorphology', 'feOffset', 'fePointLight', 'feSpecularLighting', 'feSpotLight', 'feTile', 'feTurbulence']);
|
|
159
|
+
var svgFilters = freeze(['feBlend', 'feColorMatrix', 'feComponentTransfer', 'feComposite', 'feConvolveMatrix', 'feDiffuseLighting', 'feDisplacementMap', 'feDistantLight', 'feFlood', 'feFuncA', 'feFuncB', 'feFuncG', 'feFuncR', 'feGaussianBlur', 'feImage', 'feMerge', 'feMergeNode', 'feMorphology', 'feOffset', 'fePointLight', 'feSpecularLighting', 'feSpotLight', 'feTile', 'feTurbulence']);
|
|
160
160
|
|
|
161
161
|
// List of SVG elements that are disallowed by default.
|
|
162
162
|
// We still need to know them so that we can do namespace
|
|
163
163
|
// checks properly in case one wants to add them to
|
|
164
164
|
// allow-list.
|
|
165
|
-
var svgDisallowed = freeze(['animate', 'color-profile', 'cursor', 'discard', 'fedropshadow', '
|
|
165
|
+
var svgDisallowed = freeze(['animate', 'color-profile', 'cursor', 'discard', 'fedropshadow', 'font-face', 'font-face-format', 'font-face-name', 'font-face-src', 'font-face-uri', 'foreignobject', 'hatch', 'hatchpath', 'mesh', 'meshgradient', 'meshpatch', 'meshrow', 'missing-glyph', 'script', 'set', 'solidcolor', 'unknown', 'use']);
|
|
166
166
|
|
|
167
167
|
var mathMl = freeze(['math', 'menclose', 'merror', 'mfenced', 'mfrac', 'mglyph', 'mi', 'mlabeledtr', 'mmultiscripts', 'mn', 'mo', 'mover', 'mpadded', 'mphantom', 'mroot', 'mrow', 'ms', 'mspace', 'msqrt', 'mstyle', 'msub', 'msup', 'msubsup', 'mtable', 'mtd', 'mtext', 'mtr', 'munder', 'munderover']);
|
|
168
168
|
|
|
@@ -172,9 +172,9 @@
|
|
|
172
172
|
|
|
173
173
|
var text = freeze(['#text']);
|
|
174
174
|
|
|
175
|
-
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']);
|
|
175
|
+
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', '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', 'xmlns', 'slot']);
|
|
176
176
|
|
|
177
|
-
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']);
|
|
177
|
+
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', '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']);
|
|
178
178
|
|
|
179
179
|
var mathMl$1 = 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']);
|
|
180
180
|
|
|
@@ -190,6 +190,7 @@
|
|
|
190
190
|
var IS_SCRIPT_OR_DATA = seal(/^(?:\w+script|data):/i);
|
|
191
191
|
var ATTR_WHITESPACE = seal(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g // eslint-disable-line no-control-regex
|
|
192
192
|
);
|
|
193
|
+
var DOCTYPE_NAME = seal(/^html$/i);
|
|
193
194
|
|
|
194
195
|
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
|
|
195
196
|
|
|
@@ -249,7 +250,7 @@
|
|
|
249
250
|
* Version label, exposed for easier checks
|
|
250
251
|
* if DOMPurify is up to date or not
|
|
251
252
|
*/
|
|
252
|
-
DOMPurify.version = '2.3.
|
|
253
|
+
DOMPurify.version = '2.3.6';
|
|
253
254
|
|
|
254
255
|
/**
|
|
255
256
|
* Array of elements that DOMPurify removed during sanitation.
|
|
@@ -275,8 +276,7 @@
|
|
|
275
276
|
NodeFilter = window.NodeFilter,
|
|
276
277
|
_window$NamedNodeMap = window.NamedNodeMap,
|
|
277
278
|
NamedNodeMap = _window$NamedNodeMap === undefined ? window.NamedNodeMap || window.MozNamedAttrMap : _window$NamedNodeMap,
|
|
278
|
-
|
|
279
|
-
Comment = window.Comment,
|
|
279
|
+
HTMLFormElement = window.HTMLFormElement,
|
|
280
280
|
DOMParser = window.DOMParser,
|
|
281
281
|
trustedTypes = window.trustedTypes;
|
|
282
282
|
|
|
@@ -302,7 +302,7 @@
|
|
|
302
302
|
}
|
|
303
303
|
|
|
304
304
|
var trustedTypesPolicy = _createTrustedTypesPolicy(trustedTypes, originalDocument);
|
|
305
|
-
var emptyHTML = trustedTypesPolicy
|
|
305
|
+
var emptyHTML = trustedTypesPolicy ? trustedTypesPolicy.createHTML('') : '';
|
|
306
306
|
|
|
307
307
|
var _document = document,
|
|
308
308
|
implementation = _document.implementation,
|
|
@@ -346,6 +346,33 @@
|
|
|
346
346
|
var ALLOWED_ATTR = null;
|
|
347
347
|
var DEFAULT_ALLOWED_ATTR = addToSet({}, [].concat(_toConsumableArray$1(html$1), _toConsumableArray$1(svg$1), _toConsumableArray$1(mathMl$1), _toConsumableArray$1(xml)));
|
|
348
348
|
|
|
349
|
+
/*
|
|
350
|
+
* Configure how DOMPUrify should handle custom elements and their attributes as well as customized built-in elements.
|
|
351
|
+
* @property {RegExp|Function|null} tagNameCheck one of [null, regexPattern, predicate]. Default: `null` (disallow any custom elements)
|
|
352
|
+
* @property {RegExp|Function|null} attributeNameCheck one of [null, regexPattern, predicate]. Default: `null` (disallow any attributes not on the allow list)
|
|
353
|
+
* @property {boolean} allowCustomizedBuiltInElements allow custom elements derived from built-ins if they pass CUSTOM_ELEMENT_HANDLING.tagNameCheck. Default: `false`.
|
|
354
|
+
*/
|
|
355
|
+
var CUSTOM_ELEMENT_HANDLING = Object.seal(Object.create(null, {
|
|
356
|
+
tagNameCheck: {
|
|
357
|
+
writable: true,
|
|
358
|
+
configurable: false,
|
|
359
|
+
enumerable: true,
|
|
360
|
+
value: null
|
|
361
|
+
},
|
|
362
|
+
attributeNameCheck: {
|
|
363
|
+
writable: true,
|
|
364
|
+
configurable: false,
|
|
365
|
+
enumerable: true,
|
|
366
|
+
value: null
|
|
367
|
+
},
|
|
368
|
+
allowCustomizedBuiltInElements: {
|
|
369
|
+
writable: true,
|
|
370
|
+
configurable: false,
|
|
371
|
+
enumerable: true,
|
|
372
|
+
value: false
|
|
373
|
+
}
|
|
374
|
+
}));
|
|
375
|
+
|
|
349
376
|
/* Explicitly forbidden tags (overrides ALLOWED_TAGS/ADD_TAGS) */
|
|
350
377
|
var FORBID_TAGS = null;
|
|
351
378
|
|
|
@@ -386,17 +413,6 @@
|
|
|
386
413
|
* string (or a TrustedHTML object if Trusted Types are supported) */
|
|
387
414
|
var RETURN_DOM_FRAGMENT = false;
|
|
388
415
|
|
|
389
|
-
/* If `RETURN_DOM` or `RETURN_DOM_FRAGMENT` is enabled, decide if the returned DOM
|
|
390
|
-
* `Node` is imported into the current `Document`. If this flag is not enabled the
|
|
391
|
-
* `Node` will belong (its ownerDocument) to a fresh `HTMLDocument`, created by
|
|
392
|
-
* DOMPurify.
|
|
393
|
-
*
|
|
394
|
-
* This defaults to `true` starting DOMPurify 2.2.0. Note that setting it to `false`
|
|
395
|
-
* might cause XSS from attacks hidden in closed shadowroots in case the browser
|
|
396
|
-
* supports Declarative Shadow: DOM https://web.dev/declarative-shadow-dom/
|
|
397
|
-
*/
|
|
398
|
-
var RETURN_DOM_IMPORT = true;
|
|
399
|
-
|
|
400
416
|
/* Try to return a Trusted Type object instead of a string, return a string in
|
|
401
417
|
* case Trusted Types are not supported */
|
|
402
418
|
var RETURN_TRUSTED_TYPE = false;
|
|
@@ -447,6 +463,10 @@
|
|
|
447
463
|
|
|
448
464
|
var formElement = document.createElement('form');
|
|
449
465
|
|
|
466
|
+
var isRegexOrFunction = function isRegexOrFunction(testValue) {
|
|
467
|
+
return testValue instanceof RegExp || testValue instanceof Function;
|
|
468
|
+
};
|
|
469
|
+
|
|
450
470
|
/**
|
|
451
471
|
* _parseConfig
|
|
452
472
|
*
|
|
@@ -482,7 +502,6 @@
|
|
|
482
502
|
WHOLE_DOCUMENT = cfg.WHOLE_DOCUMENT || false; // Default false
|
|
483
503
|
RETURN_DOM = cfg.RETURN_DOM || false; // Default false
|
|
484
504
|
RETURN_DOM_FRAGMENT = cfg.RETURN_DOM_FRAGMENT || false; // Default false
|
|
485
|
-
RETURN_DOM_IMPORT = cfg.RETURN_DOM_IMPORT !== false; // Default true
|
|
486
505
|
RETURN_TRUSTED_TYPE = cfg.RETURN_TRUSTED_TYPE || false; // Default false
|
|
487
506
|
FORCE_BODY = cfg.FORCE_BODY || false; // Default false
|
|
488
507
|
SANITIZE_DOM = cfg.SANITIZE_DOM !== false; // Default true
|
|
@@ -490,7 +509,22 @@
|
|
|
490
509
|
IN_PLACE = cfg.IN_PLACE || false; // Default false
|
|
491
510
|
IS_ALLOWED_URI$$1 = cfg.ALLOWED_URI_REGEXP || IS_ALLOWED_URI$$1;
|
|
492
511
|
NAMESPACE = cfg.NAMESPACE || HTML_NAMESPACE;
|
|
493
|
-
|
|
512
|
+
if (cfg.CUSTOM_ELEMENT_HANDLING && isRegexOrFunction(cfg.CUSTOM_ELEMENT_HANDLING.tagNameCheck)) {
|
|
513
|
+
CUSTOM_ELEMENT_HANDLING.tagNameCheck = cfg.CUSTOM_ELEMENT_HANDLING.tagNameCheck;
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
if (cfg.CUSTOM_ELEMENT_HANDLING && isRegexOrFunction(cfg.CUSTOM_ELEMENT_HANDLING.attributeNameCheck)) {
|
|
517
|
+
CUSTOM_ELEMENT_HANDLING.attributeNameCheck = cfg.CUSTOM_ELEMENT_HANDLING.attributeNameCheck;
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
if (cfg.CUSTOM_ELEMENT_HANDLING && typeof cfg.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements === 'boolean') {
|
|
521
|
+
CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements = cfg.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements;
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
PARSER_MEDIA_TYPE =
|
|
525
|
+
// eslint-disable-next-line unicorn/prefer-includes
|
|
526
|
+
SUPPORTED_PARSER_MEDIA_TYPES.indexOf(cfg.PARSER_MEDIA_TYPE) === -1 ? PARSER_MEDIA_TYPE = DEFAULT_PARSER_MEDIA_TYPE : PARSER_MEDIA_TYPE = cfg.PARSER_MEDIA_TYPE;
|
|
527
|
+
|
|
494
528
|
// HTML tags and attributes are not case-sensitive, converting to lowercase. Keeping XHTML as is.
|
|
495
529
|
transformCaseFunc = PARSER_MEDIA_TYPE === 'application/xhtml+xml' ? function (x) {
|
|
496
530
|
return x;
|
|
@@ -811,7 +845,9 @@
|
|
|
811
845
|
* @return {Iterator} iterator instance
|
|
812
846
|
*/
|
|
813
847
|
var _createIterator = function _createIterator(root) {
|
|
814
|
-
return createNodeIterator.call(root.ownerDocument || root, root,
|
|
848
|
+
return createNodeIterator.call(root.ownerDocument || root, root,
|
|
849
|
+
// eslint-disable-next-line no-bitwise
|
|
850
|
+
NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_TEXT, null, false);
|
|
815
851
|
};
|
|
816
852
|
|
|
817
853
|
/**
|
|
@@ -821,15 +857,7 @@
|
|
|
821
857
|
* @return {Boolean} true if clobbered, false if safe
|
|
822
858
|
*/
|
|
823
859
|
var _isClobbered = function _isClobbered(elm) {
|
|
824
|
-
|
|
825
|
-
return false;
|
|
826
|
-
}
|
|
827
|
-
|
|
828
|
-
if (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') {
|
|
829
|
-
return true;
|
|
830
|
-
}
|
|
831
|
-
|
|
832
|
-
return false;
|
|
860
|
+
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');
|
|
833
861
|
};
|
|
834
862
|
|
|
835
863
|
/**
|
|
@@ -911,6 +939,12 @@
|
|
|
911
939
|
|
|
912
940
|
/* Remove element if anything forbids its presence */
|
|
913
941
|
if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) {
|
|
942
|
+
/* Check if we have a custom element to handle */
|
|
943
|
+
if (!FORBID_TAGS[tagName] && _basicCustomElementTest(tagName)) {
|
|
944
|
+
if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, tagName)) return false;
|
|
945
|
+
if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(tagName)) return false;
|
|
946
|
+
}
|
|
947
|
+
|
|
914
948
|
/* Keep content except for bad-listed elements */
|
|
915
949
|
if (KEEP_CONTENT && !FORBID_CONTENTS[tagName]) {
|
|
916
950
|
var parentNode = getParentNode(currentNode) || currentNode.parentNode;
|
|
@@ -978,8 +1012,16 @@
|
|
|
978
1012
|
XML-compatible (https://html.spec.whatwg.org/multipage/infrastructure.html#xml-compatible and http://www.w3.org/TR/xml/#d0e804)
|
|
979
1013
|
We don't need to check the value; it's always URI safe. */
|
|
980
1014
|
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]) {
|
|
981
|
-
|
|
982
|
-
|
|
1015
|
+
if (
|
|
1016
|
+
// First condition does a very basic check if a) it's basically a valid custom element tagname AND
|
|
1017
|
+
// b) if the tagName passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck
|
|
1018
|
+
// and c) if the attribute name passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.attributeNameCheck
|
|
1019
|
+
_basicCustomElementTest(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)) ||
|
|
1020
|
+
// Alternative, second condition checks if it's an `is`-attribute, AND
|
|
1021
|
+
// the value passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck
|
|
1022
|
+
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 {
|
|
1023
|
+
return false;
|
|
1024
|
+
}
|
|
983
1025
|
/* Check value is safe. First, is attr inert? If so, is safe */
|
|
984
1026
|
} else if (URI_SAFE_ATTRIBUTES[lcName]) ; else if (regExpTest(IS_ALLOWED_URI$$1, stringReplace(value, ATTR_WHITESPACE$$1, ''))) ; else if ((lcName === 'src' || lcName === 'xlink:href' || lcName === 'href') && lcTag !== 'script' && stringIndexOf(value, 'data:') === 0 && DATA_URI_TAGS[lcTag]) ; else if (ALLOW_UNKNOWN_PROTOCOLS && !regExpTest(IS_SCRIPT_OR_DATA$$1, stringReplace(value, ATTR_WHITESPACE$$1, ''))) ; else if (!value) ; else {
|
|
985
1027
|
return false;
|
|
@@ -988,6 +1030,16 @@
|
|
|
988
1030
|
return true;
|
|
989
1031
|
};
|
|
990
1032
|
|
|
1033
|
+
/**
|
|
1034
|
+
* _basicCustomElementCheck
|
|
1035
|
+
* checks if at least one dash is included in tagName, and it's not the first char
|
|
1036
|
+
* for more sophisticated checking see https://github.com/sindresorhus/validate-element-name
|
|
1037
|
+
* @param {string} tagName name of the tag of the node to sanitize
|
|
1038
|
+
*/
|
|
1039
|
+
var _basicCustomElementTest = function _basicCustomElementTest(tagName) {
|
|
1040
|
+
return tagName.indexOf('-') > 0;
|
|
1041
|
+
};
|
|
1042
|
+
|
|
991
1043
|
/**
|
|
992
1044
|
* _sanitizeAttributes
|
|
993
1045
|
*
|
|
@@ -1184,7 +1236,15 @@
|
|
|
1184
1236
|
IN_PLACE = false;
|
|
1185
1237
|
}
|
|
1186
1238
|
|
|
1187
|
-
if (IN_PLACE)
|
|
1239
|
+
if (IN_PLACE) {
|
|
1240
|
+
/* Do some early pre-sanitization to avoid unsafe root nodes */
|
|
1241
|
+
if (dirty.nodeName) {
|
|
1242
|
+
var tagName = transformCaseFunc(dirty.nodeName);
|
|
1243
|
+
if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) {
|
|
1244
|
+
throw typeErrorCreate('root node is forbidden and cannot be sanitized in-place');
|
|
1245
|
+
}
|
|
1246
|
+
}
|
|
1247
|
+
} else if (dirty instanceof Node) {
|
|
1188
1248
|
/* If dirty is a DOM element, append to an empty document to avoid
|
|
1189
1249
|
elements being stripped by the parser */
|
|
1190
1250
|
body = _initDocument('<!---->');
|
|
@@ -1211,7 +1271,7 @@
|
|
|
1211
1271
|
|
|
1212
1272
|
/* Check we have a DOM node from the data */
|
|
1213
1273
|
if (!body) {
|
|
1214
|
-
return RETURN_DOM ? null : emptyHTML;
|
|
1274
|
+
return RETURN_DOM ? null : RETURN_TRUSTED_TYPE ? emptyHTML : '';
|
|
1215
1275
|
}
|
|
1216
1276
|
}
|
|
1217
1277
|
|
|
@@ -1266,7 +1326,7 @@
|
|
|
1266
1326
|
returnNode = body;
|
|
1267
1327
|
}
|
|
1268
1328
|
|
|
1269
|
-
if (
|
|
1329
|
+
if (ALLOWED_ATTR.shadowroot) {
|
|
1270
1330
|
/*
|
|
1271
1331
|
AdoptNode() is not used because internal state is not reset
|
|
1272
1332
|
(e.g. the past names map of a HTMLFormElement), this is safe
|
|
@@ -1282,6 +1342,11 @@
|
|
|
1282
1342
|
|
|
1283
1343
|
var serializedHTML = WHOLE_DOCUMENT ? body.outerHTML : body.innerHTML;
|
|
1284
1344
|
|
|
1345
|
+
/* Serialize doctype if allowed */
|
|
1346
|
+
if (WHOLE_DOCUMENT && ALLOWED_TAGS['!doctype'] && body.ownerDocument && body.ownerDocument.doctype && body.ownerDocument.doctype.name && regExpTest(DOCTYPE_NAME, body.ownerDocument.doctype.name)) {
|
|
1347
|
+
serializedHTML = '<!DOCTYPE ' + body.ownerDocument.doctype.name + '>\n' + serializedHTML;
|
|
1348
|
+
}
|
|
1349
|
+
|
|
1285
1350
|
/* Sanitize final string template-safe */
|
|
1286
1351
|
if (SAFE_FOR_TEMPLATES) {
|
|
1287
1352
|
serializedHTML = stringReplace(serializedHTML, MUSTACHE_EXPR$$1, ' ');
|