dompurify 2.3.1 → 2.3.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/README.md +70 -31
- package/dist/purify.cjs.js +114 -41
- package/dist/purify.cjs.js.map +1 -1
- package/dist/purify.es.js +114 -41
- package/dist/purify.es.js.map +1 -1
- package/dist/purify.js +114 -41
- 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 +4 -8
package/dist/purify.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! @license DOMPurify 2.3.
|
|
1
|
+
/*! @license DOMPurify 2.3.5 | (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.5/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
|
|
|
@@ -249,7 +249,7 @@
|
|
|
249
249
|
* Version label, exposed for easier checks
|
|
250
250
|
* if DOMPurify is up to date or not
|
|
251
251
|
*/
|
|
252
|
-
DOMPurify.version = '2.3.
|
|
252
|
+
DOMPurify.version = '2.3.5';
|
|
253
253
|
|
|
254
254
|
/**
|
|
255
255
|
* Array of elements that DOMPurify removed during sanitation.
|
|
@@ -275,8 +275,7 @@
|
|
|
275
275
|
NodeFilter = window.NodeFilter,
|
|
276
276
|
_window$NamedNodeMap = window.NamedNodeMap,
|
|
277
277
|
NamedNodeMap = _window$NamedNodeMap === undefined ? window.NamedNodeMap || window.MozNamedAttrMap : _window$NamedNodeMap,
|
|
278
|
-
|
|
279
|
-
Comment = window.Comment,
|
|
278
|
+
HTMLFormElement = window.HTMLFormElement,
|
|
280
279
|
DOMParser = window.DOMParser,
|
|
281
280
|
trustedTypes = window.trustedTypes;
|
|
282
281
|
|
|
@@ -302,7 +301,7 @@
|
|
|
302
301
|
}
|
|
303
302
|
|
|
304
303
|
var trustedTypesPolicy = _createTrustedTypesPolicy(trustedTypes, originalDocument);
|
|
305
|
-
var emptyHTML = trustedTypesPolicy
|
|
304
|
+
var emptyHTML = trustedTypesPolicy ? trustedTypesPolicy.createHTML('') : '';
|
|
306
305
|
|
|
307
306
|
var _document = document,
|
|
308
307
|
implementation = _document.implementation,
|
|
@@ -346,6 +345,33 @@
|
|
|
346
345
|
var ALLOWED_ATTR = null;
|
|
347
346
|
var DEFAULT_ALLOWED_ATTR = addToSet({}, [].concat(_toConsumableArray$1(html$1), _toConsumableArray$1(svg$1), _toConsumableArray$1(mathMl$1), _toConsumableArray$1(xml)));
|
|
348
347
|
|
|
348
|
+
/*
|
|
349
|
+
* Configure how DOMPUrify should handle custom elements and their attributes as well as customized built-in elements.
|
|
350
|
+
* @property {RegExp|Function|null} tagNameCheck one of [null, regexPattern, predicate]. Default: `null` (disallow any custom elements)
|
|
351
|
+
* @property {RegExp|Function|null} attributeNameCheck one of [null, regexPattern, predicate]. Default: `null` (disallow any attributes not on the allow list)
|
|
352
|
+
* @property {boolean} allowCustomizedBuiltInElements allow custom elements derived from built-ins if they pass CUSTOM_ELEMENT_HANDLING.tagNameCheck. Default: `false`.
|
|
353
|
+
*/
|
|
354
|
+
var CUSTOM_ELEMENT_HANDLING = Object.seal(Object.create(null, {
|
|
355
|
+
tagNameCheck: {
|
|
356
|
+
writable: true,
|
|
357
|
+
configurable: false,
|
|
358
|
+
enumerable: true,
|
|
359
|
+
value: null
|
|
360
|
+
},
|
|
361
|
+
attributeNameCheck: {
|
|
362
|
+
writable: true,
|
|
363
|
+
configurable: false,
|
|
364
|
+
enumerable: true,
|
|
365
|
+
value: null
|
|
366
|
+
},
|
|
367
|
+
allowCustomizedBuiltInElements: {
|
|
368
|
+
writable: true,
|
|
369
|
+
configurable: false,
|
|
370
|
+
enumerable: true,
|
|
371
|
+
value: false
|
|
372
|
+
}
|
|
373
|
+
}));
|
|
374
|
+
|
|
349
375
|
/* Explicitly forbidden tags (overrides ALLOWED_TAGS/ADD_TAGS) */
|
|
350
376
|
var FORBID_TAGS = null;
|
|
351
377
|
|
|
@@ -386,17 +412,6 @@
|
|
|
386
412
|
* string (or a TrustedHTML object if Trusted Types are supported) */
|
|
387
413
|
var RETURN_DOM_FRAGMENT = false;
|
|
388
414
|
|
|
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
415
|
/* Try to return a Trusted Type object instead of a string, return a string in
|
|
401
416
|
* case Trusted Types are not supported */
|
|
402
417
|
var RETURN_TRUSTED_TYPE = false;
|
|
@@ -433,6 +448,12 @@
|
|
|
433
448
|
var NAMESPACE = HTML_NAMESPACE;
|
|
434
449
|
var IS_EMPTY_INPUT = false;
|
|
435
450
|
|
|
451
|
+
/* Parsing of strict XHTML documents */
|
|
452
|
+
var PARSER_MEDIA_TYPE = void 0;
|
|
453
|
+
var SUPPORTED_PARSER_MEDIA_TYPES = ['application/xhtml+xml', 'text/html'];
|
|
454
|
+
var DEFAULT_PARSER_MEDIA_TYPE = 'text/html';
|
|
455
|
+
var transformCaseFunc = void 0;
|
|
456
|
+
|
|
436
457
|
/* Keep a reference to config to pass to hooks */
|
|
437
458
|
var CONFIG = null;
|
|
438
459
|
|
|
@@ -441,6 +462,10 @@
|
|
|
441
462
|
|
|
442
463
|
var formElement = document.createElement('form');
|
|
443
464
|
|
|
465
|
+
var isRegexOrFunction = function isRegexOrFunction(testValue) {
|
|
466
|
+
return testValue instanceof RegExp || testValue instanceof Function;
|
|
467
|
+
};
|
|
468
|
+
|
|
444
469
|
/**
|
|
445
470
|
* _parseConfig
|
|
446
471
|
*
|
|
@@ -476,7 +501,6 @@
|
|
|
476
501
|
WHOLE_DOCUMENT = cfg.WHOLE_DOCUMENT || false; // Default false
|
|
477
502
|
RETURN_DOM = cfg.RETURN_DOM || false; // Default false
|
|
478
503
|
RETURN_DOM_FRAGMENT = cfg.RETURN_DOM_FRAGMENT || false; // Default false
|
|
479
|
-
RETURN_DOM_IMPORT = cfg.RETURN_DOM_IMPORT !== false; // Default true
|
|
480
504
|
RETURN_TRUSTED_TYPE = cfg.RETURN_TRUSTED_TYPE || false; // Default false
|
|
481
505
|
FORCE_BODY = cfg.FORCE_BODY || false; // Default false
|
|
482
506
|
SANITIZE_DOM = cfg.SANITIZE_DOM !== false; // Default true
|
|
@@ -484,6 +508,27 @@
|
|
|
484
508
|
IN_PLACE = cfg.IN_PLACE || false; // Default false
|
|
485
509
|
IS_ALLOWED_URI$$1 = cfg.ALLOWED_URI_REGEXP || IS_ALLOWED_URI$$1;
|
|
486
510
|
NAMESPACE = cfg.NAMESPACE || HTML_NAMESPACE;
|
|
511
|
+
if (cfg.CUSTOM_ELEMENT_HANDLING && isRegexOrFunction(cfg.CUSTOM_ELEMENT_HANDLING.tagNameCheck)) {
|
|
512
|
+
CUSTOM_ELEMENT_HANDLING.tagNameCheck = cfg.CUSTOM_ELEMENT_HANDLING.tagNameCheck;
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
if (cfg.CUSTOM_ELEMENT_HANDLING && isRegexOrFunction(cfg.CUSTOM_ELEMENT_HANDLING.attributeNameCheck)) {
|
|
516
|
+
CUSTOM_ELEMENT_HANDLING.attributeNameCheck = cfg.CUSTOM_ELEMENT_HANDLING.attributeNameCheck;
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
if (cfg.CUSTOM_ELEMENT_HANDLING && typeof cfg.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements === 'boolean') {
|
|
520
|
+
CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements = cfg.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements;
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
PARSER_MEDIA_TYPE =
|
|
524
|
+
// eslint-disable-next-line unicorn/prefer-includes
|
|
525
|
+
SUPPORTED_PARSER_MEDIA_TYPES.indexOf(cfg.PARSER_MEDIA_TYPE) === -1 ? PARSER_MEDIA_TYPE = DEFAULT_PARSER_MEDIA_TYPE : PARSER_MEDIA_TYPE = cfg.PARSER_MEDIA_TYPE;
|
|
526
|
+
|
|
527
|
+
// HTML tags and attributes are not case-sensitive, converting to lowercase. Keeping XHTML as is.
|
|
528
|
+
transformCaseFunc = PARSER_MEDIA_TYPE === 'application/xhtml+xml' ? function (x) {
|
|
529
|
+
return x;
|
|
530
|
+
} : stringToLowerCase;
|
|
531
|
+
|
|
487
532
|
if (SAFE_FOR_TEMPLATES) {
|
|
488
533
|
ALLOW_DATA_ATTR = false;
|
|
489
534
|
}
|
|
@@ -752,6 +797,11 @@
|
|
|
752
797
|
leadingWhitespace = matches && matches[0];
|
|
753
798
|
}
|
|
754
799
|
|
|
800
|
+
if (PARSER_MEDIA_TYPE === 'application/xhtml+xml') {
|
|
801
|
+
// Root of XHTML doc must contain xmlns declaration (see https://www.w3.org/TR/xhtml1/normative.html#strict)
|
|
802
|
+
dirty = '<html xmlns="http://www.w3.org/1999/xhtml"><head></head><body>' + dirty + '</body></html>';
|
|
803
|
+
}
|
|
804
|
+
|
|
755
805
|
var dirtyPayload = trustedTypesPolicy ? trustedTypesPolicy.createHTML(dirty) : dirty;
|
|
756
806
|
/*
|
|
757
807
|
* Use the DOMParser API by default, fallback later if needs be
|
|
@@ -759,7 +809,7 @@
|
|
|
759
809
|
*/
|
|
760
810
|
if (NAMESPACE === HTML_NAMESPACE) {
|
|
761
811
|
try {
|
|
762
|
-
doc = new DOMParser().parseFromString(dirtyPayload,
|
|
812
|
+
doc = new DOMParser().parseFromString(dirtyPayload, PARSER_MEDIA_TYPE);
|
|
763
813
|
} catch (_) {}
|
|
764
814
|
}
|
|
765
815
|
|
|
@@ -804,15 +854,7 @@
|
|
|
804
854
|
* @return {Boolean} true if clobbered, false if safe
|
|
805
855
|
*/
|
|
806
856
|
var _isClobbered = function _isClobbered(elm) {
|
|
807
|
-
|
|
808
|
-
return false;
|
|
809
|
-
}
|
|
810
|
-
|
|
811
|
-
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') {
|
|
812
|
-
return true;
|
|
813
|
-
}
|
|
814
|
-
|
|
815
|
-
return false;
|
|
857
|
+
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');
|
|
816
858
|
};
|
|
817
859
|
|
|
818
860
|
/**
|
|
@@ -872,7 +914,7 @@
|
|
|
872
914
|
}
|
|
873
915
|
|
|
874
916
|
/* Now let's check the element's type and name */
|
|
875
|
-
var tagName =
|
|
917
|
+
var tagName = transformCaseFunc(currentNode.nodeName);
|
|
876
918
|
|
|
877
919
|
/* Execute a hook if present */
|
|
878
920
|
_executeHook('uponSanitizeElement', currentNode, {
|
|
@@ -908,6 +950,11 @@
|
|
|
908
950
|
}
|
|
909
951
|
}
|
|
910
952
|
|
|
953
|
+
if (!FORBID_TAGS[tagName] && _basicCustomElementTest(tagName)) {
|
|
954
|
+
if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, tagName)) return false;
|
|
955
|
+
if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(tagName)) return false;
|
|
956
|
+
}
|
|
957
|
+
|
|
911
958
|
_forceRemove(currentNode);
|
|
912
959
|
return true;
|
|
913
960
|
}
|
|
@@ -961,8 +1008,16 @@
|
|
|
961
1008
|
XML-compatible (https://html.spec.whatwg.org/multipage/infrastructure.html#xml-compatible and http://www.w3.org/TR/xml/#d0e804)
|
|
962
1009
|
We don't need to check the value; it's always URI safe. */
|
|
963
1010
|
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]) {
|
|
964
|
-
|
|
965
|
-
|
|
1011
|
+
if (
|
|
1012
|
+
// First condition does a very basic check if a) it's basically a valid custom element tagname AND
|
|
1013
|
+
// b) if the tagName passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck
|
|
1014
|
+
// and c) if the attribute name passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.attributeNameCheck
|
|
1015
|
+
_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)) ||
|
|
1016
|
+
// Alternative, second condition checks if it's an `is`-attribute, AND
|
|
1017
|
+
// the value passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck
|
|
1018
|
+
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 {
|
|
1019
|
+
return false;
|
|
1020
|
+
}
|
|
966
1021
|
/* Check value is safe. First, is attr inert? If so, is safe */
|
|
967
1022
|
} 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 {
|
|
968
1023
|
return false;
|
|
@@ -971,6 +1026,16 @@
|
|
|
971
1026
|
return true;
|
|
972
1027
|
};
|
|
973
1028
|
|
|
1029
|
+
/**
|
|
1030
|
+
* _basicCustomElementCheck
|
|
1031
|
+
* checks if at least one dash is included in tagName, and it's not the first char
|
|
1032
|
+
* for more sophisticated checking see https://github.com/sindresorhus/validate-element-name
|
|
1033
|
+
* @param {string} tagName name of the tag of the node to sanitize
|
|
1034
|
+
*/
|
|
1035
|
+
var _basicCustomElementTest = function _basicCustomElementTest(tagName) {
|
|
1036
|
+
return tagName.indexOf('-') > 0;
|
|
1037
|
+
};
|
|
1038
|
+
|
|
974
1039
|
/**
|
|
975
1040
|
* _sanitizeAttributes
|
|
976
1041
|
*
|
|
@@ -1013,7 +1078,7 @@
|
|
|
1013
1078
|
namespaceURI = _attr.namespaceURI;
|
|
1014
1079
|
|
|
1015
1080
|
value = stringTrim(attr.value);
|
|
1016
|
-
lcName =
|
|
1081
|
+
lcName = transformCaseFunc(name);
|
|
1017
1082
|
|
|
1018
1083
|
/* Execute a hook if present */
|
|
1019
1084
|
hookEvent.attrName = lcName;
|
|
@@ -1048,7 +1113,7 @@
|
|
|
1048
1113
|
}
|
|
1049
1114
|
|
|
1050
1115
|
/* Is `value` valid for this attribute? */
|
|
1051
|
-
var lcTag = currentNode.nodeName
|
|
1116
|
+
var lcTag = transformCaseFunc(currentNode.nodeName);
|
|
1052
1117
|
if (!_isValidAttribute(lcTag, lcName, value)) {
|
|
1053
1118
|
continue;
|
|
1054
1119
|
}
|
|
@@ -1167,7 +1232,15 @@
|
|
|
1167
1232
|
IN_PLACE = false;
|
|
1168
1233
|
}
|
|
1169
1234
|
|
|
1170
|
-
if (IN_PLACE)
|
|
1235
|
+
if (IN_PLACE) {
|
|
1236
|
+
/* Do some early pre-sanitization to avoid unsafe root nodes */
|
|
1237
|
+
if (dirty.nodeName) {
|
|
1238
|
+
var tagName = transformCaseFunc(dirty.nodeName);
|
|
1239
|
+
if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) {
|
|
1240
|
+
throw typeErrorCreate('root node is forbidden and cannot be sanitized in-place');
|
|
1241
|
+
}
|
|
1242
|
+
}
|
|
1243
|
+
} else if (dirty instanceof Node) {
|
|
1171
1244
|
/* If dirty is a DOM element, append to an empty document to avoid
|
|
1172
1245
|
elements being stripped by the parser */
|
|
1173
1246
|
body = _initDocument('<!---->');
|
|
@@ -1194,7 +1267,7 @@
|
|
|
1194
1267
|
|
|
1195
1268
|
/* Check we have a DOM node from the data */
|
|
1196
1269
|
if (!body) {
|
|
1197
|
-
return RETURN_DOM ? null : emptyHTML;
|
|
1270
|
+
return RETURN_DOM ? null : RETURN_TRUSTED_TYPE ? emptyHTML : '';
|
|
1198
1271
|
}
|
|
1199
1272
|
}
|
|
1200
1273
|
|
|
@@ -1249,7 +1322,7 @@
|
|
|
1249
1322
|
returnNode = body;
|
|
1250
1323
|
}
|
|
1251
1324
|
|
|
1252
|
-
if (
|
|
1325
|
+
if (ALLOWED_ATTR.shadowroot) {
|
|
1253
1326
|
/*
|
|
1254
1327
|
AdoptNode() is not used because internal state is not reset
|
|
1255
1328
|
(e.g. the past names map of a HTMLFormElement), this is safe
|
|
@@ -1311,8 +1384,8 @@
|
|
|
1311
1384
|
_parseConfig({});
|
|
1312
1385
|
}
|
|
1313
1386
|
|
|
1314
|
-
var lcTag =
|
|
1315
|
-
var lcName =
|
|
1387
|
+
var lcTag = transformCaseFunc(tag);
|
|
1388
|
+
var lcName = transformCaseFunc(attr);
|
|
1316
1389
|
return _isValidAttribute(lcTag, lcName, value);
|
|
1317
1390
|
};
|
|
1318
1391
|
|