dompurify 3.4.6 → 3.4.8
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/LICENSE-MPL +373 -0
- package/README.md +19 -2
- package/dist/purify.cjs.d.ts +2 -2
- package/dist/purify.cjs.js +116 -69
- package/dist/purify.cjs.js.map +1 -1
- package/dist/purify.es.d.mts +2 -2
- package/dist/purify.es.mjs +116 -69
- package/dist/purify.es.mjs.map +1 -1
- package/dist/purify.js +116 -69
- 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 +15 -14
- package/src/config.ts +1 -1
- package/src/purify.ts +141 -66
package/dist/purify.es.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! @license DOMPurify 3.4.
|
|
1
|
+
/*! @license DOMPurify 3.4.8 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.4.8/LICENSE */
|
|
2
2
|
|
|
3
3
|
function _arrayLikeToArray(r, a) {
|
|
4
4
|
(null == a || a > r.length) && (a = r.length);
|
|
@@ -403,7 +403,7 @@ const _createHooksMap = function _createHooksMap() {
|
|
|
403
403
|
function createDOMPurify() {
|
|
404
404
|
let window = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : getGlobal();
|
|
405
405
|
const DOMPurify = root => createDOMPurify(root);
|
|
406
|
-
DOMPurify.version = '3.4.
|
|
406
|
+
DOMPurify.version = '3.4.8';
|
|
407
407
|
DOMPurify.removed = [];
|
|
408
408
|
if (!window || !window.document || window.document.nodeType !== NODE_TYPE.document || !window.Element) {
|
|
409
409
|
// Not running in a browser, provide a factory function
|
|
@@ -448,6 +448,23 @@ function createDOMPurify() {
|
|
|
448
448
|
}
|
|
449
449
|
let trustedTypesPolicy;
|
|
450
450
|
let emptyHTML = '';
|
|
451
|
+
// Tracks whether we are already inside a call to the configured Trusted Types
|
|
452
|
+
// policy's `createHTML`. If the supplied `TRUSTED_TYPES_POLICY.createHTML`
|
|
453
|
+
// itself calls `DOMPurify.sanitize` (the cause of #1422), `sanitize` would
|
|
454
|
+
// re-enter the policy and recurse until the stack overflows. We detect that
|
|
455
|
+
// re-entry and throw a clear, actionable error instead.
|
|
456
|
+
let IN_POLICY_CREATE_HTML = 0;
|
|
457
|
+
const _createTrustedHTML = function _createTrustedHTML(html) {
|
|
458
|
+
if (IN_POLICY_CREATE_HTML > 0) {
|
|
459
|
+
throw typeErrorCreate('The configured TRUSTED_TYPES_POLICY.createHTML must not call ' + 'DOMPurify.sanitize, as that causes infinite recursion. Do not pass ' + 'a policy whose createHTML wraps DOMPurify as TRUSTED_TYPES_POLICY; ' + 'see the "DOMPurify and Trusted Types" section of the README.');
|
|
460
|
+
}
|
|
461
|
+
IN_POLICY_CREATE_HTML++;
|
|
462
|
+
try {
|
|
463
|
+
return trustedTypesPolicy.createHTML(html);
|
|
464
|
+
} finally {
|
|
465
|
+
IN_POLICY_CREATE_HTML--;
|
|
466
|
+
}
|
|
467
|
+
};
|
|
451
468
|
const _document = document,
|
|
452
469
|
implementation = _document.implementation,
|
|
453
470
|
createNodeIterator = _document.createNodeIterator,
|
|
@@ -775,19 +792,47 @@ function createDOMPurify() {
|
|
|
775
792
|
throw typeErrorCreate('TRUSTED_TYPES_POLICY configuration option must provide a "createScriptURL" hook.');
|
|
776
793
|
}
|
|
777
794
|
// Overwrite existing TrustedTypes policy.
|
|
795
|
+
const previousTrustedTypesPolicy = trustedTypesPolicy;
|
|
778
796
|
trustedTypesPolicy = cfg.TRUSTED_TYPES_POLICY;
|
|
779
|
-
// Sign local variables required by `sanitize`.
|
|
780
|
-
|
|
797
|
+
// Sign local variables required by `sanitize`. If the supplied policy's
|
|
798
|
+
// `createHTML` is circular (i.e. it calls `DOMPurify.sanitize`), this
|
|
799
|
+
// throws via the re-entrancy guard. Restore the previous policy first so
|
|
800
|
+
// the instance is not left in a poisoned state. See #1422.
|
|
801
|
+
try {
|
|
802
|
+
emptyHTML = _createTrustedHTML('');
|
|
803
|
+
} catch (error) {
|
|
804
|
+
trustedTypesPolicy = previousTrustedTypesPolicy;
|
|
805
|
+
throw error;
|
|
806
|
+
}
|
|
781
807
|
} else {
|
|
782
808
|
// Uninitialized policy, attempt to initialize the internal dompurify policy.
|
|
783
|
-
if (trustedTypesPolicy === undefined) {
|
|
809
|
+
if (trustedTypesPolicy === undefined && cfg.TRUSTED_TYPES_POLICY !== null) {
|
|
784
810
|
trustedTypesPolicy = _createTrustedTypesPolicy(trustedTypes, currentScript);
|
|
785
811
|
}
|
|
786
812
|
// If creating the internal policy succeeded sign internal variables.
|
|
787
|
-
|
|
788
|
-
|
|
813
|
+
// Note: a falsy `trustedTypesPolicy` (null when policy creation failed or
|
|
814
|
+
// was skipped via `TRUSTED_TYPES_POLICY: null`, or undefined when no
|
|
815
|
+
// policy has been initialized yet) must be excluded here, otherwise we
|
|
816
|
+
// would call `.createHTML` on a non-policy and throw. See #1422.
|
|
817
|
+
if (trustedTypesPolicy && typeof emptyHTML === 'string') {
|
|
818
|
+
emptyHTML = _createTrustedHTML('');
|
|
789
819
|
}
|
|
790
820
|
}
|
|
821
|
+
/*
|
|
822
|
+
* Mirror the clone-before-mutate pattern already applied above for
|
|
823
|
+
* cfg.ADD_TAGS / cfg.ADD_ATTR: if any uponSanitize* hook is
|
|
824
|
+
* registered AND the set still points at the default constant,
|
|
825
|
+
* clone it. The hook then mutates the clone (in-call widening
|
|
826
|
+
* still works exactly as documented) and the next default-cfg
|
|
827
|
+
* call rebinds to the untouched original via the reassignment at
|
|
828
|
+
* the top of this function.
|
|
829
|
+
*/
|
|
830
|
+
if ((hooks.uponSanitizeElement.length > 0 || hooks.uponSanitizeAttribute.length > 0) && ALLOWED_TAGS === DEFAULT_ALLOWED_TAGS) {
|
|
831
|
+
ALLOWED_TAGS = clone(ALLOWED_TAGS);
|
|
832
|
+
}
|
|
833
|
+
if (hooks.uponSanitizeAttribute.length > 0 && ALLOWED_ATTR === DEFAULT_ALLOWED_ATTR) {
|
|
834
|
+
ALLOWED_ATTR = clone(ALLOWED_ATTR);
|
|
835
|
+
}
|
|
791
836
|
// Prevent further manipulation of configuration.
|
|
792
837
|
// Not available in IE8, Safari 5, etc.
|
|
793
838
|
if (freeze) {
|
|
@@ -947,7 +992,7 @@ function createDOMPurify() {
|
|
|
947
992
|
// Root of XHTML doc must contain xmlns declaration (see https://www.w3.org/TR/xhtml1/normative.html#strict)
|
|
948
993
|
dirty = '<html xmlns="http://www.w3.org/1999/xhtml"><head></head><body>' + dirty + '</body></html>';
|
|
949
994
|
}
|
|
950
|
-
const dirtyPayload = trustedTypesPolicy ?
|
|
995
|
+
const dirtyPayload = trustedTypesPolicy ? _createTrustedHTML(dirty) : dirty;
|
|
951
996
|
/*
|
|
952
997
|
* Use the DOMParser API by default, fallback later if needs be
|
|
953
998
|
* DOMParser not work for svg when has multiple root element.
|
|
@@ -1006,7 +1051,8 @@ function createDOMPurify() {
|
|
|
1006
1051
|
*
|
|
1007
1052
|
* @param node The root element whose character data should be scrubbed.
|
|
1008
1053
|
*/
|
|
1009
|
-
const
|
|
1054
|
+
const _scrubTemplateExpressions2 = function _scrubTemplateExpressions(node) {
|
|
1055
|
+
var _node$querySelectorAl, _node$querySelectorAl2;
|
|
1010
1056
|
node.normalize();
|
|
1011
1057
|
const walker = createNodeIterator.call(node.ownerDocument || node, node,
|
|
1012
1058
|
// eslint-disable-next-line no-bitwise
|
|
@@ -1020,6 +1066,15 @@ function createDOMPurify() {
|
|
|
1020
1066
|
currentNode.data = data;
|
|
1021
1067
|
currentNode = walker.nextNode();
|
|
1022
1068
|
}
|
|
1069
|
+
// NodeIterator does not descend into <template>.content per the DOM spec,
|
|
1070
|
+
// so we must explicitly recurse into each template's content fragment,
|
|
1071
|
+
// mirroring the approach used by _sanitizeShadowDOM.
|
|
1072
|
+
const templates = (_node$querySelectorAl = (_node$querySelectorAl2 = node.querySelectorAll) === null || _node$querySelectorAl2 === void 0 ? void 0 : _node$querySelectorAl2.call(node, 'template')) !== null && _node$querySelectorAl !== void 0 ? _node$querySelectorAl : [];
|
|
1073
|
+
arrayForEach(Array.from(templates), tmpl => {
|
|
1074
|
+
if (_isDocumentFragment(tmpl.content)) {
|
|
1075
|
+
_scrubTemplateExpressions2(tmpl.content);
|
|
1076
|
+
}
|
|
1077
|
+
});
|
|
1023
1078
|
};
|
|
1024
1079
|
/**
|
|
1025
1080
|
* _isClobbered
|
|
@@ -1030,32 +1085,6 @@ function createDOMPurify() {
|
|
|
1030
1085
|
* on direct reads. We use this check at the IN_PLACE entry-point and
|
|
1031
1086
|
* during attribute sanitization to refuse clobbered forms.
|
|
1032
1087
|
*
|
|
1033
|
-
* Realm safety (GHSA-hpcv-96wg-7vj8): every check in this function must
|
|
1034
|
-
* work for foreign-realm forms — e.g. a <form> created inside a same-
|
|
1035
|
-
* origin iframe and then handed to a parent-realm DOMPurify instance
|
|
1036
|
-
* with IN_PLACE: true. The original implementation used
|
|
1037
|
-
* `element instanceof HTMLFormElement` and `element.attributes
|
|
1038
|
-
* instanceof NamedNodeMap`, both of which are realm-bound: a foreign-
|
|
1039
|
-
* realm form is an instance of the *foreign* realm's HTMLFormElement,
|
|
1040
|
-
* not the parent realm's. The instanceof short-circuited to false and
|
|
1041
|
-
* the function returned false (= not clobbered) regardless of how
|
|
1042
|
-
* thoroughly the form was clobbered. Sanitize then walked a clobbered
|
|
1043
|
-
* .attributes and missed every attribute on the form root, leaving
|
|
1044
|
-
* onmouseover / onclick / formaction / etc. intact.
|
|
1045
|
-
*
|
|
1046
|
-
* The realm-independent replacements:
|
|
1047
|
-
* - HTMLFormElement detection — read the tag name through the cached
|
|
1048
|
-
* Node.prototype.nodeName getter. WebIDL getters operate on internal
|
|
1049
|
-
* slots that exist on every real Node regardless of which realm
|
|
1050
|
-
* minted the JS wrapper, so getNodeName(foreignForm) === "FORM".
|
|
1051
|
-
* - NamedNodeMap detection — compare the direct .attributes read
|
|
1052
|
-
* against the cached Element.prototype.attributes getter. Same
|
|
1053
|
-
* equality-probe pattern we use for .childNodes: if a clobbering
|
|
1054
|
-
* child shadows the named property, the two reads diverge; if not,
|
|
1055
|
-
* both return the same NamedNodeMap (same-realm OR foreign-realm —
|
|
1056
|
-
* doesn't matter, both are the canonical attributes object for the
|
|
1057
|
-
* node).
|
|
1058
|
-
*
|
|
1059
1088
|
* @param element element to check for clobbering attacks
|
|
1060
1089
|
* @return true if clobbered, false if safe
|
|
1061
1090
|
*/
|
|
@@ -1077,6 +1106,14 @@ function createDOMPurify() {
|
|
|
1077
1106
|
// (same-realm OR foreign-realm) has both reads pointing at the same
|
|
1078
1107
|
// canonical NamedNodeMap.
|
|
1079
1108
|
element.attributes !== getAttributes(element) || typeof element.removeAttribute !== 'function' || typeof element.setAttribute !== 'function' || typeof element.namespaceURI !== 'string' || typeof element.insertBefore !== 'function' || typeof element.hasChildNodes !== 'function' ||
|
|
1109
|
+
// NodeType clobbering probe. Cached Node.prototype.nodeType getter
|
|
1110
|
+
// returns the integer 1 for any Element regardless of realm; direct
|
|
1111
|
+
// read on a clobbered form (e.g. <input name="nodeType">) returns
|
|
1112
|
+
// the named child element. Cheap addition — nodeType is read from
|
|
1113
|
+
// an internal slot, no serialization cost — and removes a residual
|
|
1114
|
+
// clobbering surface used by several mXSS / PI / comment branches
|
|
1115
|
+
// in _sanitizeElements that compare currentNode.nodeType directly.
|
|
1116
|
+
element.nodeType !== getNodeType(element) ||
|
|
1080
1117
|
// HTMLFormElement has [LegacyOverrideBuiltIns]: a descendant named
|
|
1081
1118
|
// "childNodes" shadows the prototype getter. Direct reads of
|
|
1082
1119
|
// form.childNodes from a clobbered form return the named child
|
|
@@ -1093,14 +1130,6 @@ function createDOMPurify() {
|
|
|
1093
1130
|
/**
|
|
1094
1131
|
* Checks whether the given value is a DocumentFragment from any realm.
|
|
1095
1132
|
*
|
|
1096
|
-
* Realm safety (GHSA-hpcv-96wg-7vj8): the original sites used
|
|
1097
|
-
* `value instanceof DocumentFragment`, which is realm-bound — a fragment
|
|
1098
|
-
* from a foreign realm (template content or shadow root from an iframe
|
|
1099
|
-
* document) is an instance of the foreign realm's DocumentFragment, not
|
|
1100
|
-
* the parent realm's, so the check returned false and the template-
|
|
1101
|
-
* content / shadow-root recursion was silently skipped. The attacker
|
|
1102
|
-
* payload inside survived untouched.
|
|
1103
|
-
*
|
|
1104
1133
|
* The realm-independent replacement reads `nodeType` through the cached
|
|
1105
1134
|
* Node.prototype getter and compares to the DOCUMENT_FRAGMENT_NODE
|
|
1106
1135
|
* constant (11). nodeType is a numeric value resolved from the node's
|
|
@@ -1127,12 +1156,6 @@ function createDOMPurify() {
|
|
|
1127
1156
|
* sanitize() to silently stringify them and reset IN_PLACE to false,
|
|
1128
1157
|
* returning the original node unsanitized. See GHSA-4w3q-35jp-p934.
|
|
1129
1158
|
*
|
|
1130
|
-
* Implementation: call the cached `nodeType` getter from Node.prototype
|
|
1131
|
-
* directly on the value. This bypasses any clobbered instance property
|
|
1132
|
-
* (e.g. a child element named "nodeType") and works across realms
|
|
1133
|
-
* because the WebIDL `nodeType` getter reads an internal slot that
|
|
1134
|
-
* every real Node has, regardless of which window minted it.
|
|
1135
|
-
*
|
|
1136
1159
|
* @param value object to check whether it's a DOM node
|
|
1137
1160
|
* @return true if value is a DOM node from any realm
|
|
1138
1161
|
*/
|
|
@@ -1170,7 +1193,7 @@ function createDOMPurify() {
|
|
|
1170
1193
|
return true;
|
|
1171
1194
|
}
|
|
1172
1195
|
/* Now let's check the element's type and name */
|
|
1173
|
-
const tagName = transformCaseFunc(currentNode.nodeName);
|
|
1196
|
+
const tagName = transformCaseFunc(getNodeName ? getNodeName(currentNode) : currentNode.nodeName);
|
|
1174
1197
|
/* Execute a hook if present */
|
|
1175
1198
|
_executeHooks(hooks.uponSanitizeElement, currentNode, {
|
|
1176
1199
|
tagName,
|
|
@@ -1207,10 +1230,17 @@ function createDOMPurify() {
|
|
|
1207
1230
|
return false;
|
|
1208
1231
|
}
|
|
1209
1232
|
}
|
|
1210
|
-
/* Keep content except for bad-listed elements
|
|
1233
|
+
/* Keep content except for bad-listed elements.
|
|
1234
|
+
Use the cached prototype getters exclusively — the previous code
|
|
1235
|
+
had `|| currentNode.parentNode` / `|| currentNode.childNodes`
|
|
1236
|
+
fallbacks, but the cached getters always return the canonical
|
|
1237
|
+
value (or null for a real parent-less node), so the fallback
|
|
1238
|
+
path was dead in safe cases and a clobbering surface in unsafe
|
|
1239
|
+
ones. Falsy cached results stay falsy; the `if (childNodes &&
|
|
1240
|
+
parentNode)` check already gates correctly. */
|
|
1211
1241
|
if (KEEP_CONTENT && !FORBID_CONTENTS[tagName]) {
|
|
1212
|
-
const parentNode = getParentNode(currentNode)
|
|
1213
|
-
const childNodes = getChildNodes(currentNode)
|
|
1242
|
+
const parentNode = getParentNode(currentNode);
|
|
1243
|
+
const childNodes = getChildNodes(currentNode);
|
|
1214
1244
|
if (childNodes && parentNode) {
|
|
1215
1245
|
const childCount = childNodes.length;
|
|
1216
1246
|
for (let i = childCount - 1; i >= 0; --i) {
|
|
@@ -1406,7 +1436,7 @@ function createDOMPurify() {
|
|
|
1406
1436
|
switch (trustedTypes.getAttributeType(lcTag, lcName)) {
|
|
1407
1437
|
case 'TrustedHTML':
|
|
1408
1438
|
{
|
|
1409
|
-
value =
|
|
1439
|
+
value = _createTrustedHTML(value);
|
|
1410
1440
|
break;
|
|
1411
1441
|
}
|
|
1412
1442
|
case 'TrustedScriptURL':
|
|
@@ -1463,6 +1493,24 @@ function createDOMPurify() {
|
|
|
1463
1493
|
if (_isDocumentFragment(shadowNode.content)) {
|
|
1464
1494
|
_sanitizeShadowDOM2(shadowNode.content);
|
|
1465
1495
|
}
|
|
1496
|
+
/* An element iterated here may itself host an attached
|
|
1497
|
+
shadow root. The default NodeIterator does not enter shadow
|
|
1498
|
+
trees, so a shadow root nested inside template.content was
|
|
1499
|
+
previously reached by no walk at all (the pre-pass at
|
|
1500
|
+
_sanitizeAttachedShadowRoots descends via childNodes, which
|
|
1501
|
+
doesn't enter template.content; the template-content recursion
|
|
1502
|
+
above iterates the content but never inspected shadowRoot).
|
|
1503
|
+
Walk it explicitly. The nodeType guard avoids reading
|
|
1504
|
+
shadowRoot off text / comment / CDATA / PI nodes that the
|
|
1505
|
+
iterator also surfaces. */
|
|
1506
|
+
const shadowNodeType = getNodeType ? getNodeType(shadowNode) : shadowNode.nodeType;
|
|
1507
|
+
if (shadowNodeType === NODE_TYPE.element) {
|
|
1508
|
+
const innerSr = getShadowRoot ? getShadowRoot(shadowNode) : shadowNode.shadowRoot;
|
|
1509
|
+
if (_isDocumentFragment(innerSr)) {
|
|
1510
|
+
_sanitizeAttachedShadowRoots2(innerSr);
|
|
1511
|
+
_sanitizeShadowDOM2(innerSr);
|
|
1512
|
+
}
|
|
1513
|
+
}
|
|
1466
1514
|
}
|
|
1467
1515
|
/* Execute a hook if present */
|
|
1468
1516
|
_executeHooks(hooks.afterSanitizeShadowDOM, fragment, null);
|
|
@@ -1484,17 +1532,6 @@ function createDOMPurify() {
|
|
|
1484
1532
|
* existing _sanitizeShadowDOM template-content recursion) stay
|
|
1485
1533
|
* untouched — string-input paths are not affected.
|
|
1486
1534
|
*
|
|
1487
|
-
* DOM-Clobbering hardening: HTMLFormElement carries the WebIDL
|
|
1488
|
-
* [LegacyOverrideBuiltIns] extended attribute, so a descendant element
|
|
1489
|
-
* named `nodeType`, `shadowRoot`, or `childNodes` shadows the matching
|
|
1490
|
-
* prototype getter on the form. Reading those properties directly off
|
|
1491
|
-
* the node would let an attacker steer this walk past shadow hosts
|
|
1492
|
-
* (e.g. <input name="childNodes"> collapses the form's child list to
|
|
1493
|
-
* the input itself, so descent stops dead and any shadow root deeper
|
|
1494
|
-
* in the subtree is never sanitized). Every property access here is
|
|
1495
|
-
* therefore routed through the cached prototype getter; the form's
|
|
1496
|
-
* named-property getter cannot intercept those reads.
|
|
1497
|
-
*
|
|
1498
1535
|
* @param root the subtree root to walk for attached shadow roots
|
|
1499
1536
|
*/
|
|
1500
1537
|
const _sanitizeAttachedShadowRoots2 = function _sanitizeAttachedShadowRoots(root) {
|
|
@@ -1530,6 +1567,16 @@ function createDOMPurify() {
|
|
|
1530
1567
|
for (const child of snapshot) {
|
|
1531
1568
|
_sanitizeAttachedShadowRoots2(child);
|
|
1532
1569
|
}
|
|
1570
|
+
/* When the root is a <template>, also descend into root.content */
|
|
1571
|
+
if (nodeType === NODE_TYPE.element) {
|
|
1572
|
+
const rootName = getNodeName ? getNodeName(root) : null;
|
|
1573
|
+
if (typeof rootName === 'string' && transformCaseFunc(rootName) === 'template') {
|
|
1574
|
+
const content = root.content;
|
|
1575
|
+
if (_isDocumentFragment(content)) {
|
|
1576
|
+
_sanitizeAttachedShadowRoots2(content);
|
|
1577
|
+
}
|
|
1578
|
+
}
|
|
1579
|
+
}
|
|
1533
1580
|
};
|
|
1534
1581
|
// eslint-disable-next-line complexity
|
|
1535
1582
|
DOMPurify.sanitize = function (dirty) {
|
|
@@ -1620,7 +1667,7 @@ function createDOMPurify() {
|
|
|
1620
1667
|
if (!RETURN_DOM && !SAFE_FOR_TEMPLATES && !WHOLE_DOCUMENT &&
|
|
1621
1668
|
// eslint-disable-next-line unicorn/prefer-includes
|
|
1622
1669
|
dirty.indexOf('<') === -1) {
|
|
1623
|
-
return trustedTypesPolicy && RETURN_TRUSTED_TYPE ?
|
|
1670
|
+
return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? _createTrustedHTML(dirty) : dirty;
|
|
1624
1671
|
}
|
|
1625
1672
|
/* Initialize the document to work on */
|
|
1626
1673
|
body = _initDocument(dirty);
|
|
@@ -1652,14 +1699,14 @@ function createDOMPurify() {
|
|
|
1652
1699
|
/* If we sanitized `dirty` in-place, return it. */
|
|
1653
1700
|
if (IN_PLACE) {
|
|
1654
1701
|
if (SAFE_FOR_TEMPLATES) {
|
|
1655
|
-
|
|
1702
|
+
_scrubTemplateExpressions2(dirty);
|
|
1656
1703
|
}
|
|
1657
1704
|
return dirty;
|
|
1658
1705
|
}
|
|
1659
1706
|
/* Return sanitized string or DOM */
|
|
1660
1707
|
if (RETURN_DOM) {
|
|
1661
1708
|
if (SAFE_FOR_TEMPLATES) {
|
|
1662
|
-
|
|
1709
|
+
_scrubTemplateExpressions2(body);
|
|
1663
1710
|
}
|
|
1664
1711
|
if (RETURN_DOM_FRAGMENT) {
|
|
1665
1712
|
returnNode = createDocumentFragment.call(body.ownerDocument);
|
|
@@ -1693,7 +1740,7 @@ function createDOMPurify() {
|
|
|
1693
1740
|
serializedHTML = stringReplace(serializedHTML, expr, ' ');
|
|
1694
1741
|
});
|
|
1695
1742
|
}
|
|
1696
|
-
return trustedTypesPolicy && RETURN_TRUSTED_TYPE ?
|
|
1743
|
+
return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? _createTrustedHTML(serializedHTML) : serializedHTML;
|
|
1697
1744
|
};
|
|
1698
1745
|
DOMPurify.setConfig = function () {
|
|
1699
1746
|
let cfg = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|