release: v4.8.9 security hardening patch
- upgrade DOMPurify to patched release (fixes high-severity XSS GHSA-87xg-pxx2-7hvx) - upgrade esbuild build dependency; npm audit now reports 0 vulnerabilities - stop tracking config/ice-servers.js (TURN credentials); add example template - production logger no longer prints error context or info/debug output - bump version to 4.8.9 across header, manifest, README, init message - update SECURITY.md supported-release table to v4.8.x
This commit is contained in:
Vendored
+491
-177
@@ -5,7 +5,11 @@ var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __commonJS = (cb, mod) => function __require() {
|
||||
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
||||
try {
|
||||
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
||||
} catch (e) {
|
||||
throw mod = 0, e;
|
||||
}
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
@@ -954,7 +958,7 @@ function isRegex(value) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
var html$1 = 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", "search", "section", "select", "selectedcontent", "shadow", "slot", "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"]);
|
||||
var html$1 = 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", "search", "section", "select", "shadow", "slot", "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"]);
|
||||
var svg$1 = freeze(["svg", "a", "altglyph", "altglyphdef", "altglyphitem", "animatecolor", "animatemotion", "animatetransform", "circle", "clippath", "defs", "desc", "ellipse", "enterkeyhint", "exportparts", "filter", "font", "g", "glyph", "glyphref", "hkern", "image", "inputmode", "line", "lineargradient", "marker", "mask", "metadata", "mpath", "part", "path", "pattern", "polygon", "polyline", "radialgradient", "rect", "stop", "style", "switch", "symbol", "text", "textpath", "title", "tref", "tspan", "view", "vkern"]);
|
||||
var svgFilters = freeze(["feBlend", "feColorMatrix", "feComponentTransfer", "feComposite", "feConvolveMatrix", "feDiffuseLighting", "feDisplacementMap", "feDistantLight", "feDropShadow", "feFlood", "feFuncA", "feFuncB", "feFuncG", "feFuncR", "feGaussianBlur", "feImage", "feMerge", "feMergeNode", "feMorphology", "feOffset", "fePointLight", "feSpecularLighting", "feSpotLight", "feTile", "feTurbulence"]);
|
||||
var svgDisallowed = freeze(["animate", "color-profile", "cursor", "discard", "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"]);
|
||||
@@ -981,13 +985,26 @@ var ATTR_WHITESPACE = seal(
|
||||
);
|
||||
var DOCTYPE_NAME = seal(/^html$/i);
|
||||
var CUSTOM_ELEMENT = seal(/^[a-z][.\w]*(-[.\w]+)+$/i);
|
||||
var ELEMENT_MARKUP_PROBE = seal(/<[/\w!]/g);
|
||||
var COMMENT_MARKUP_PROBE = seal(/<[/\w]/g);
|
||||
var FALLBACK_TAG_CLOSE = seal(/<\/no(script|embed|frames)/i);
|
||||
var SELF_CLOSING_TAG = seal(/\/>/i);
|
||||
var NODE_TYPE = {
|
||||
element: 1,
|
||||
attribute: 2,
|
||||
text: 3,
|
||||
cdataSection: 4,
|
||||
entityReference: 5,
|
||||
// Deprecated
|
||||
progressingInstruction: 7,
|
||||
entityNode: 6,
|
||||
// Deprecated
|
||||
processingInstruction: 7,
|
||||
comment: 8,
|
||||
document: 9
|
||||
document: 9,
|
||||
documentType: 10,
|
||||
documentFragment: 11,
|
||||
notation: 12
|
||||
// Deprecated
|
||||
};
|
||||
var getGlobal = function getGlobal2() {
|
||||
return typeof window === "undefined" ? null : window;
|
||||
@@ -1029,10 +1046,13 @@ var _createHooksMap = function _createHooksMap2() {
|
||||
uponSanitizeShadowNode: []
|
||||
};
|
||||
};
|
||||
var _resolveSetOption = function _resolveSetOption2(cfg, key, fallback, options) {
|
||||
return objectHasOwnProperty(cfg, key) && arrayIsArray(cfg[key]) ? addToSet(options.base ? clone(options.base) : {}, cfg[key], options.transform) : fallback;
|
||||
};
|
||||
function createDOMPurify() {
|
||||
let window2 = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : getGlobal();
|
||||
const DOMPurify = (root) => createDOMPurify(root);
|
||||
DOMPurify.version = "3.4.4";
|
||||
DOMPurify.version = "3.4.10";
|
||||
DOMPurify.removed = [];
|
||||
if (!window2 || !window2.document || window2.document.nodeType !== NODE_TYPE.document || !window2.Element) {
|
||||
DOMPurify.isSupported = false;
|
||||
@@ -1041,14 +1061,21 @@ function createDOMPurify() {
|
||||
let document2 = window2.document;
|
||||
const originalDocument = document2;
|
||||
const currentScript = originalDocument.currentScript;
|
||||
const DocumentFragment = window2.DocumentFragment, HTMLTemplateElement = window2.HTMLTemplateElement, Node = window2.Node, Element = window2.Element, NodeFilter = window2.NodeFilter, _window$NamedNodeMap = window2.NamedNodeMap, NamedNodeMap = _window$NamedNodeMap === void 0 ? window2.NamedNodeMap || window2.MozNamedAttrMap : _window$NamedNodeMap, HTMLFormElement = window2.HTMLFormElement, DOMParser = window2.DOMParser, trustedTypes = window2.trustedTypes;
|
||||
window2.DocumentFragment;
|
||||
const HTMLTemplateElement = window2.HTMLTemplateElement, Node = window2.Node, Element = window2.Element, NodeFilter = window2.NodeFilter, _window$NamedNodeMap = window2.NamedNodeMap;
|
||||
_window$NamedNodeMap === void 0 ? window2.NamedNodeMap || window2.MozNamedAttrMap : _window$NamedNodeMap;
|
||||
window2.HTMLFormElement;
|
||||
const DOMParser = window2.DOMParser, trustedTypes = window2.trustedTypes;
|
||||
const ElementPrototype = Element.prototype;
|
||||
const cloneNode = lookupGetter(ElementPrototype, "cloneNode");
|
||||
const remove = lookupGetter(ElementPrototype, "remove");
|
||||
const getNextSibling = lookupGetter(ElementPrototype, "nextSibling");
|
||||
const getChildNodes = lookupGetter(ElementPrototype, "childNodes");
|
||||
const getParentNode = lookupGetter(ElementPrototype, "parentNode");
|
||||
const getShadowRoot = lookupGetter(ElementPrototype, "shadowRoot");
|
||||
const getAttributes = lookupGetter(ElementPrototype, "attributes");
|
||||
const getNodeType = Node && Node.prototype ? lookupGetter(Node.prototype, "nodeType") : null;
|
||||
const getNodeName = Node && Node.prototype ? lookupGetter(Node.prototype, "nodeName") : null;
|
||||
if (typeof HTMLTemplateElement === "function") {
|
||||
const template = document2.createElement("template");
|
||||
if (template.content && template.content.ownerDocument) {
|
||||
@@ -1057,6 +1084,39 @@ function createDOMPurify() {
|
||||
}
|
||||
let trustedTypesPolicy;
|
||||
let emptyHTML = "";
|
||||
let defaultTrustedTypesPolicy;
|
||||
let defaultTrustedTypesPolicyResolved = false;
|
||||
let IN_TRUSTED_TYPES_POLICY = 0;
|
||||
const _assertNotInTrustedTypesPolicy = function _assertNotInTrustedTypesPolicy2() {
|
||||
if (IN_TRUSTED_TYPES_POLICY > 0) {
|
||||
throw typeErrorCreate('A configured TRUSTED_TYPES_POLICY callback (createHTML or createScriptURL) must not call DOMPurify.sanitize, as that causes infinite recursion. Do not pass a policy whose callbacks wrap DOMPurify as TRUSTED_TYPES_POLICY; see the "DOMPurify and Trusted Types" section of the README.');
|
||||
}
|
||||
};
|
||||
const _createTrustedHTML = function _createTrustedHTML2(html2) {
|
||||
_assertNotInTrustedTypesPolicy();
|
||||
IN_TRUSTED_TYPES_POLICY++;
|
||||
try {
|
||||
return trustedTypesPolicy.createHTML(html2);
|
||||
} finally {
|
||||
IN_TRUSTED_TYPES_POLICY--;
|
||||
}
|
||||
};
|
||||
const _createTrustedScriptURL = function _createTrustedScriptURL2(scriptUrl) {
|
||||
_assertNotInTrustedTypesPolicy();
|
||||
IN_TRUSTED_TYPES_POLICY++;
|
||||
try {
|
||||
return trustedTypesPolicy.createScriptURL(scriptUrl);
|
||||
} finally {
|
||||
IN_TRUSTED_TYPES_POLICY--;
|
||||
}
|
||||
};
|
||||
const _getDefaultTrustedTypesPolicy = function _getDefaultTrustedTypesPolicy2() {
|
||||
if (!defaultTrustedTypesPolicyResolved) {
|
||||
defaultTrustedTypesPolicy = _createTrustedTypesPolicy(trustedTypes, currentScript);
|
||||
defaultTrustedTypesPolicyResolved = true;
|
||||
}
|
||||
return defaultTrustedTypesPolicy;
|
||||
};
|
||||
const _document = document2, implementation = _document.implementation, createNodeIterator = _document.createNodeIterator, createDocumentFragment = _document.createDocumentFragment, getElementsByTagName = _document.getElementsByTagName;
|
||||
const importNode = originalDocument.importNode;
|
||||
let hooks = _createHooksMap();
|
||||
@@ -1122,7 +1182,43 @@ function createDOMPurify() {
|
||||
let IN_PLACE = false;
|
||||
let USE_PROFILES = {};
|
||||
let FORBID_CONTENTS = null;
|
||||
const DEFAULT_FORBID_CONTENTS = addToSet({}, ["annotation-xml", "audio", "colgroup", "desc", "foreignobject", "head", "iframe", "math", "mi", "mn", "mo", "ms", "mtext", "noembed", "noframes", "noscript", "plaintext", "script", "style", "svg", "template", "thead", "title", "video", "xmp"]);
|
||||
const DEFAULT_FORBID_CONTENTS = addToSet({}, [
|
||||
"annotation-xml",
|
||||
"audio",
|
||||
"colgroup",
|
||||
"desc",
|
||||
"foreignobject",
|
||||
"head",
|
||||
"iframe",
|
||||
"math",
|
||||
"mi",
|
||||
"mn",
|
||||
"mo",
|
||||
"ms",
|
||||
"mtext",
|
||||
"noembed",
|
||||
"noframes",
|
||||
"noscript",
|
||||
"plaintext",
|
||||
"script",
|
||||
// <selectedcontent> mirrors the selected <option>'s subtree, cloned by
|
||||
// the UA (customizable <select>) — including any on* handlers — and the
|
||||
// engine re-mirrors synchronously whenever a removal changes which
|
||||
// option/selectedcontent is current, even inside DOMPurify's inert
|
||||
// DOMParser document. Hoisting its children on removal re-inserts a fresh
|
||||
// mirror target ahead of the walk, which the engine refills, looping
|
||||
// forever (DoS) and amplifying output. Dropping its content on removal
|
||||
// (rather than hoisting) breaks that cascade; the content is a duplicate
|
||||
// of the option, which is sanitized on its own. See campaign-3 F1/F6.
|
||||
"selectedcontent",
|
||||
"style",
|
||||
"svg",
|
||||
"template",
|
||||
"thead",
|
||||
"title",
|
||||
"video",
|
||||
"xmp"
|
||||
]);
|
||||
let DATA_URI_TAGS = null;
|
||||
const DEFAULT_DATA_URI_TAGS = addToSet({}, ["audio", "video", "img", "source", "image", "track"]);
|
||||
let URI_SAFE_ATTRIBUTES = null;
|
||||
@@ -1134,8 +1230,10 @@ function createDOMPurify() {
|
||||
let IS_EMPTY_INPUT = false;
|
||||
let ALLOWED_NAMESPACES = null;
|
||||
const DEFAULT_ALLOWED_NAMESPACES = addToSet({}, [MATHML_NAMESPACE, SVG_NAMESPACE, HTML_NAMESPACE], stringToString);
|
||||
let MATHML_TEXT_INTEGRATION_POINTS = addToSet({}, ["mi", "mo", "mn", "ms", "mtext"]);
|
||||
let HTML_INTEGRATION_POINTS = addToSet({}, ["annotation-xml"]);
|
||||
const DEFAULT_MATHML_TEXT_INTEGRATION_POINTS = freeze(["mi", "mo", "mn", "ms", "mtext"]);
|
||||
let MATHML_TEXT_INTEGRATION_POINTS = addToSet({}, DEFAULT_MATHML_TEXT_INTEGRATION_POINTS);
|
||||
const DEFAULT_HTML_INTEGRATION_POINTS = freeze(["annotation-xml"]);
|
||||
let HTML_INTEGRATION_POINTS = addToSet({}, DEFAULT_HTML_INTEGRATION_POINTS);
|
||||
const COMMON_SVG_AND_HTML_ELEMENTS = addToSet({}, ["title", "style", "font", "a", "script"]);
|
||||
let PARSER_MEDIA_TYPE = null;
|
||||
const SUPPORTED_PARSER_MEDIA_TYPES = ["application/xhtml+xml", "text/html"];
|
||||
@@ -1158,14 +1256,32 @@ function createDOMPurify() {
|
||||
PARSER_MEDIA_TYPE = // eslint-disable-next-line unicorn/prefer-includes
|
||||
SUPPORTED_PARSER_MEDIA_TYPES.indexOf(cfg.PARSER_MEDIA_TYPE) === -1 ? DEFAULT_PARSER_MEDIA_TYPE : cfg.PARSER_MEDIA_TYPE;
|
||||
transformCaseFunc = PARSER_MEDIA_TYPE === "application/xhtml+xml" ? stringToString : stringToLowerCase;
|
||||
ALLOWED_TAGS = objectHasOwnProperty(cfg, "ALLOWED_TAGS") && arrayIsArray(cfg.ALLOWED_TAGS) ? addToSet({}, cfg.ALLOWED_TAGS, transformCaseFunc) : DEFAULT_ALLOWED_TAGS;
|
||||
ALLOWED_ATTR = objectHasOwnProperty(cfg, "ALLOWED_ATTR") && arrayIsArray(cfg.ALLOWED_ATTR) ? addToSet({}, cfg.ALLOWED_ATTR, transformCaseFunc) : DEFAULT_ALLOWED_ATTR;
|
||||
ALLOWED_NAMESPACES = objectHasOwnProperty(cfg, "ALLOWED_NAMESPACES") && arrayIsArray(cfg.ALLOWED_NAMESPACES) ? addToSet({}, cfg.ALLOWED_NAMESPACES, stringToString) : DEFAULT_ALLOWED_NAMESPACES;
|
||||
URI_SAFE_ATTRIBUTES = objectHasOwnProperty(cfg, "ADD_URI_SAFE_ATTR") && arrayIsArray(cfg.ADD_URI_SAFE_ATTR) ? addToSet(clone(DEFAULT_URI_SAFE_ATTRIBUTES), cfg.ADD_URI_SAFE_ATTR, transformCaseFunc) : DEFAULT_URI_SAFE_ATTRIBUTES;
|
||||
DATA_URI_TAGS = objectHasOwnProperty(cfg, "ADD_DATA_URI_TAGS") && arrayIsArray(cfg.ADD_DATA_URI_TAGS) ? addToSet(clone(DEFAULT_DATA_URI_TAGS), cfg.ADD_DATA_URI_TAGS, transformCaseFunc) : DEFAULT_DATA_URI_TAGS;
|
||||
FORBID_CONTENTS = objectHasOwnProperty(cfg, "FORBID_CONTENTS") && arrayIsArray(cfg.FORBID_CONTENTS) ? addToSet({}, cfg.FORBID_CONTENTS, transformCaseFunc) : DEFAULT_FORBID_CONTENTS;
|
||||
FORBID_TAGS = objectHasOwnProperty(cfg, "FORBID_TAGS") && arrayIsArray(cfg.FORBID_TAGS) ? addToSet({}, cfg.FORBID_TAGS, transformCaseFunc) : clone({});
|
||||
FORBID_ATTR = objectHasOwnProperty(cfg, "FORBID_ATTR") && arrayIsArray(cfg.FORBID_ATTR) ? addToSet({}, cfg.FORBID_ATTR, transformCaseFunc) : clone({});
|
||||
ALLOWED_TAGS = _resolveSetOption(cfg, "ALLOWED_TAGS", DEFAULT_ALLOWED_TAGS, {
|
||||
transform: transformCaseFunc
|
||||
});
|
||||
ALLOWED_ATTR = _resolveSetOption(cfg, "ALLOWED_ATTR", DEFAULT_ALLOWED_ATTR, {
|
||||
transform: transformCaseFunc
|
||||
});
|
||||
ALLOWED_NAMESPACES = _resolveSetOption(cfg, "ALLOWED_NAMESPACES", DEFAULT_ALLOWED_NAMESPACES, {
|
||||
transform: stringToString
|
||||
});
|
||||
URI_SAFE_ATTRIBUTES = _resolveSetOption(cfg, "ADD_URI_SAFE_ATTR", DEFAULT_URI_SAFE_ATTRIBUTES, {
|
||||
transform: transformCaseFunc,
|
||||
base: DEFAULT_URI_SAFE_ATTRIBUTES
|
||||
});
|
||||
DATA_URI_TAGS = _resolveSetOption(cfg, "ADD_DATA_URI_TAGS", DEFAULT_DATA_URI_TAGS, {
|
||||
transform: transformCaseFunc,
|
||||
base: DEFAULT_DATA_URI_TAGS
|
||||
});
|
||||
FORBID_CONTENTS = _resolveSetOption(cfg, "FORBID_CONTENTS", DEFAULT_FORBID_CONTENTS, {
|
||||
transform: transformCaseFunc
|
||||
});
|
||||
FORBID_TAGS = _resolveSetOption(cfg, "FORBID_TAGS", clone({}), {
|
||||
transform: transformCaseFunc
|
||||
});
|
||||
FORBID_ATTR = _resolveSetOption(cfg, "FORBID_ATTR", clone({}), {
|
||||
transform: transformCaseFunc
|
||||
});
|
||||
USE_PROFILES = objectHasOwnProperty(cfg, "USE_PROFILES") ? cfg.USE_PROFILES && typeof cfg.USE_PROFILES === "object" ? clone(cfg.USE_PROFILES) : cfg.USE_PROFILES : false;
|
||||
ALLOW_ARIA_ATTR = cfg.ALLOW_ARIA_ATTR !== false;
|
||||
ALLOW_DATA_ATTR = cfg.ALLOW_DATA_ATTR !== false;
|
||||
@@ -1184,8 +1300,8 @@ function createDOMPurify() {
|
||||
IN_PLACE = cfg.IN_PLACE || false;
|
||||
IS_ALLOWED_URI$1 = isRegex(cfg.ALLOWED_URI_REGEXP) ? cfg.ALLOWED_URI_REGEXP : IS_ALLOWED_URI;
|
||||
NAMESPACE = typeof cfg.NAMESPACE === "string" ? cfg.NAMESPACE : HTML_NAMESPACE;
|
||||
MATHML_TEXT_INTEGRATION_POINTS = objectHasOwnProperty(cfg, "MATHML_TEXT_INTEGRATION_POINTS") && cfg.MATHML_TEXT_INTEGRATION_POINTS && typeof cfg.MATHML_TEXT_INTEGRATION_POINTS === "object" ? clone(cfg.MATHML_TEXT_INTEGRATION_POINTS) : addToSet({}, ["mi", "mo", "mn", "ms", "mtext"]);
|
||||
HTML_INTEGRATION_POINTS = objectHasOwnProperty(cfg, "HTML_INTEGRATION_POINTS") && cfg.HTML_INTEGRATION_POINTS && typeof cfg.HTML_INTEGRATION_POINTS === "object" ? clone(cfg.HTML_INTEGRATION_POINTS) : addToSet({}, ["annotation-xml"]);
|
||||
MATHML_TEXT_INTEGRATION_POINTS = objectHasOwnProperty(cfg, "MATHML_TEXT_INTEGRATION_POINTS") && cfg.MATHML_TEXT_INTEGRATION_POINTS && typeof cfg.MATHML_TEXT_INTEGRATION_POINTS === "object" ? clone(cfg.MATHML_TEXT_INTEGRATION_POINTS) : addToSet({}, DEFAULT_MATHML_TEXT_INTEGRATION_POINTS);
|
||||
HTML_INTEGRATION_POINTS = objectHasOwnProperty(cfg, "HTML_INTEGRATION_POINTS") && cfg.HTML_INTEGRATION_POINTS && typeof cfg.HTML_INTEGRATION_POINTS === "object" ? clone(cfg.HTML_INTEGRATION_POINTS) : addToSet({}, DEFAULT_HTML_INTEGRATION_POINTS);
|
||||
const customElementHandling = objectHasOwnProperty(cfg, "CUSTOM_ELEMENT_HANDLING") && cfg.CUSTOM_ELEMENT_HANDLING && typeof cfg.CUSTOM_ELEMENT_HANDLING === "object" ? clone(cfg.CUSTOM_ELEMENT_HANDLING) : create(null);
|
||||
CUSTOM_ELEMENT_HANDLING = create(null);
|
||||
if (objectHasOwnProperty(customElementHandling, "tagNameCheck") && isRegexOrFunction(customElementHandling.tagNameCheck)) {
|
||||
@@ -1197,6 +1313,7 @@ function createDOMPurify() {
|
||||
if (objectHasOwnProperty(customElementHandling, "allowCustomizedBuiltInElements") && typeof customElementHandling.allowCustomizedBuiltInElements === "boolean") {
|
||||
CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements = customElementHandling.allowCustomizedBuiltInElements;
|
||||
}
|
||||
seal(CUSTOM_ELEMENT_HANDLING);
|
||||
if (SAFE_FOR_TEMPLATES) {
|
||||
ALLOW_DATA_ATTR = false;
|
||||
}
|
||||
@@ -1280,16 +1397,31 @@ function createDOMPurify() {
|
||||
if (typeof cfg.TRUSTED_TYPES_POLICY.createScriptURL !== "function") {
|
||||
throw typeErrorCreate('TRUSTED_TYPES_POLICY configuration option must provide a "createScriptURL" hook.');
|
||||
}
|
||||
const previousTrustedTypesPolicy = trustedTypesPolicy;
|
||||
trustedTypesPolicy = cfg.TRUSTED_TYPES_POLICY;
|
||||
emptyHTML = trustedTypesPolicy.createHTML("");
|
||||
try {
|
||||
emptyHTML = _createTrustedHTML("");
|
||||
} catch (error) {
|
||||
trustedTypesPolicy = previousTrustedTypesPolicy;
|
||||
throw error;
|
||||
}
|
||||
} else if (cfg.TRUSTED_TYPES_POLICY === null) {
|
||||
trustedTypesPolicy = void 0;
|
||||
emptyHTML = "";
|
||||
} else {
|
||||
if (trustedTypesPolicy === void 0) {
|
||||
trustedTypesPolicy = _createTrustedTypesPolicy(trustedTypes, currentScript);
|
||||
trustedTypesPolicy = _getDefaultTrustedTypesPolicy();
|
||||
}
|
||||
if (trustedTypesPolicy !== null && typeof emptyHTML === "string") {
|
||||
emptyHTML = trustedTypesPolicy.createHTML("");
|
||||
if (trustedTypesPolicy && typeof emptyHTML === "string") {
|
||||
emptyHTML = _createTrustedHTML("");
|
||||
}
|
||||
}
|
||||
if ((hooks.uponSanitizeElement.length > 0 || hooks.uponSanitizeAttribute.length > 0) && ALLOWED_TAGS === DEFAULT_ALLOWED_TAGS) {
|
||||
ALLOWED_TAGS = clone(ALLOWED_TAGS);
|
||||
}
|
||||
if (hooks.uponSanitizeAttribute.length > 0 && ALLOWED_ATTR === DEFAULT_ALLOWED_ATTR) {
|
||||
ALLOWED_ATTR = clone(ALLOWED_ATTR);
|
||||
}
|
||||
if (freeze) {
|
||||
freeze(cfg);
|
||||
}
|
||||
@@ -1297,6 +1429,33 @@ function createDOMPurify() {
|
||||
};
|
||||
const ALL_SVG_TAGS = addToSet({}, [...svg$1, ...svgFilters, ...svgDisallowed]);
|
||||
const ALL_MATHML_TAGS = addToSet({}, [...mathMl$1, ...mathMlDisallowed]);
|
||||
const _checkSvgNamespace = function _checkSvgNamespace2(tagName, parent, parentTagName) {
|
||||
if (parent.namespaceURI === HTML_NAMESPACE) {
|
||||
return tagName === "svg";
|
||||
}
|
||||
if (parent.namespaceURI === MATHML_NAMESPACE) {
|
||||
return tagName === "svg" && (parentTagName === "annotation-xml" || MATHML_TEXT_INTEGRATION_POINTS[parentTagName]);
|
||||
}
|
||||
return Boolean(ALL_SVG_TAGS[tagName]);
|
||||
};
|
||||
const _checkMathMlNamespace = function _checkMathMlNamespace2(tagName, parent, parentTagName) {
|
||||
if (parent.namespaceURI === HTML_NAMESPACE) {
|
||||
return tagName === "math";
|
||||
}
|
||||
if (parent.namespaceURI === SVG_NAMESPACE) {
|
||||
return tagName === "math" && HTML_INTEGRATION_POINTS[parentTagName];
|
||||
}
|
||||
return Boolean(ALL_MATHML_TAGS[tagName]);
|
||||
};
|
||||
const _checkHtmlNamespace = function _checkHtmlNamespace2(tagName, parent, parentTagName) {
|
||||
if (parent.namespaceURI === SVG_NAMESPACE && !HTML_INTEGRATION_POINTS[parentTagName]) {
|
||||
return false;
|
||||
}
|
||||
if (parent.namespaceURI === MATHML_NAMESPACE && !MATHML_TEXT_INTEGRATION_POINTS[parentTagName]) {
|
||||
return false;
|
||||
}
|
||||
return !ALL_MATHML_TAGS[tagName] && (COMMON_SVG_AND_HTML_ELEMENTS[tagName] || !ALL_SVG_TAGS[tagName]);
|
||||
};
|
||||
const _checkValidNamespace = function _checkValidNamespace2(element) {
|
||||
let parent = getParentNode(element);
|
||||
if (!parent || !parent.tagName) {
|
||||
@@ -1311,31 +1470,13 @@ function createDOMPurify() {
|
||||
return false;
|
||||
}
|
||||
if (element.namespaceURI === SVG_NAMESPACE) {
|
||||
if (parent.namespaceURI === HTML_NAMESPACE) {
|
||||
return tagName === "svg";
|
||||
}
|
||||
if (parent.namespaceURI === MATHML_NAMESPACE) {
|
||||
return tagName === "svg" && (parentTagName === "annotation-xml" || MATHML_TEXT_INTEGRATION_POINTS[parentTagName]);
|
||||
}
|
||||
return Boolean(ALL_SVG_TAGS[tagName]);
|
||||
return _checkSvgNamespace(tagName, parent, parentTagName);
|
||||
}
|
||||
if (element.namespaceURI === MATHML_NAMESPACE) {
|
||||
if (parent.namespaceURI === HTML_NAMESPACE) {
|
||||
return tagName === "math";
|
||||
}
|
||||
if (parent.namespaceURI === SVG_NAMESPACE) {
|
||||
return tagName === "math" && HTML_INTEGRATION_POINTS[parentTagName];
|
||||
}
|
||||
return Boolean(ALL_MATHML_TAGS[tagName]);
|
||||
return _checkMathMlNamespace(tagName, parent, parentTagName);
|
||||
}
|
||||
if (element.namespaceURI === HTML_NAMESPACE) {
|
||||
if (parent.namespaceURI === SVG_NAMESPACE && !HTML_INTEGRATION_POINTS[parentTagName]) {
|
||||
return false;
|
||||
}
|
||||
if (parent.namespaceURI === MATHML_NAMESPACE && !MATHML_TEXT_INTEGRATION_POINTS[parentTagName]) {
|
||||
return false;
|
||||
}
|
||||
return !ALL_MATHML_TAGS[tagName] && (COMMON_SVG_AND_HTML_ELEMENTS[tagName] || !ALL_SVG_TAGS[tagName]);
|
||||
return _checkHtmlNamespace(tagName, parent, parentTagName);
|
||||
}
|
||||
if (PARSER_MEDIA_TYPE === "application/xhtml+xml" && ALLOWED_NAMESPACES[element.namespaceURI]) {
|
||||
return true;
|
||||
@@ -1350,6 +1491,37 @@ function createDOMPurify() {
|
||||
getParentNode(node).removeChild(node);
|
||||
} catch (_) {
|
||||
remove(node);
|
||||
if (!getParentNode(node)) {
|
||||
throw typeErrorCreate("a node selected for removal could not be detached from its tree and cannot be safely returned; refusing to sanitize in place");
|
||||
}
|
||||
}
|
||||
};
|
||||
const _neutralizeRoot = function _neutralizeRoot2(root) {
|
||||
const childNodes = getChildNodes(root);
|
||||
if (childNodes) {
|
||||
const snapshot = [];
|
||||
arrayForEach(childNodes, (child) => {
|
||||
arrayPush(snapshot, child);
|
||||
});
|
||||
arrayForEach(snapshot, (child) => {
|
||||
try {
|
||||
remove(child);
|
||||
} catch (_) {
|
||||
}
|
||||
});
|
||||
}
|
||||
const attributes = getAttributes(root);
|
||||
if (attributes) {
|
||||
for (let i = attributes.length - 1; i >= 0; --i) {
|
||||
const attribute = attributes[i];
|
||||
const name = attribute && attribute.name;
|
||||
if (typeof name === "string") {
|
||||
try {
|
||||
root.removeAttribute(name);
|
||||
} catch (_) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
const _removeAttribute = function _removeAttribute2(name, element) {
|
||||
@@ -1379,6 +1551,39 @@ function createDOMPurify() {
|
||||
}
|
||||
}
|
||||
};
|
||||
const _stripDisallowedAttributes = function _stripDisallowedAttributes2(element) {
|
||||
const attributes = getAttributes(element);
|
||||
if (!attributes) {
|
||||
return;
|
||||
}
|
||||
for (let i = attributes.length - 1; i >= 0; --i) {
|
||||
const attribute = attributes[i];
|
||||
const name = attribute && attribute.name;
|
||||
if (typeof name !== "string" || ALLOWED_ATTR[transformCaseFunc(name)]) {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
element.removeAttribute(name);
|
||||
} catch (_) {
|
||||
}
|
||||
}
|
||||
};
|
||||
const _neutralizeSubtree = function _neutralizeSubtree2(root) {
|
||||
const stack = [root];
|
||||
while (stack.length > 0) {
|
||||
const node = stack.pop();
|
||||
const nodeType = getNodeType ? getNodeType(node) : node.nodeType;
|
||||
if (nodeType === NODE_TYPE.element) {
|
||||
_stripDisallowedAttributes(node);
|
||||
}
|
||||
const childNodes = getChildNodes(node);
|
||||
if (childNodes) {
|
||||
for (let i = childNodes.length - 1; i >= 0; --i) {
|
||||
stack.push(childNodes[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
const _initDocument = function _initDocument2(dirty) {
|
||||
let doc = null;
|
||||
let leadingWhitespace = null;
|
||||
@@ -1391,7 +1596,7 @@ function createDOMPurify() {
|
||||
if (PARSER_MEDIA_TYPE === "application/xhtml+xml" && NAMESPACE === HTML_NAMESPACE) {
|
||||
dirty = '<html xmlns="http://www.w3.org/1999/xhtml"><head></head><body>' + dirty + "</body></html>";
|
||||
}
|
||||
const dirtyPayload = trustedTypesPolicy ? trustedTypesPolicy.createHTML(dirty) : dirty;
|
||||
const dirtyPayload = trustedTypesPolicy ? _createTrustedHTML(dirty) : dirty;
|
||||
if (NAMESPACE === HTML_NAMESPACE) {
|
||||
try {
|
||||
doc = new DOMParser().parseFromString(dirtyPayload, PARSER_MEDIA_TYPE);
|
||||
@@ -1423,7 +1628,14 @@ function createDOMPurify() {
|
||||
null
|
||||
);
|
||||
};
|
||||
const _scrubTemplateExpressions = function _scrubTemplateExpressions2(node) {
|
||||
const _stripTemplateExpressions = function _stripTemplateExpressions2(value) {
|
||||
value = stringReplace(value, MUSTACHE_EXPR$1, " ");
|
||||
value = stringReplace(value, ERB_EXPR$1, " ");
|
||||
value = stringReplace(value, TMPLIT_EXPR$1, " ");
|
||||
return value;
|
||||
};
|
||||
const _scrubTemplateExpressions2 = function _scrubTemplateExpressions(node) {
|
||||
var _node$querySelectorAl;
|
||||
node.normalize();
|
||||
const walker = createNodeIterator.call(
|
||||
node.ownerDocument || node,
|
||||
@@ -1434,16 +1646,60 @@ function createDOMPurify() {
|
||||
);
|
||||
let currentNode = walker.nextNode();
|
||||
while (currentNode) {
|
||||
let data = currentNode.data;
|
||||
arrayForEach([MUSTACHE_EXPR$1, ERB_EXPR$1, TMPLIT_EXPR$1], (expr) => {
|
||||
data = stringReplace(data, expr, " ");
|
||||
});
|
||||
currentNode.data = data;
|
||||
currentNode.data = _stripTemplateExpressions(currentNode.data);
|
||||
currentNode = walker.nextNode();
|
||||
}
|
||||
const templates = (_node$querySelectorAl = node.querySelectorAll) === null || _node$querySelectorAl === void 0 ? void 0 : _node$querySelectorAl.call(node, "template");
|
||||
if (templates) {
|
||||
arrayForEach(templates, (tmpl) => {
|
||||
if (_isDocumentFragment(tmpl.content)) {
|
||||
_scrubTemplateExpressions2(tmpl.content);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
const _isClobbered = function _isClobbered2(element) {
|
||||
return element instanceof HTMLFormElement && (typeof element.nodeName !== "string" || typeof element.textContent !== "string" || typeof element.removeChild !== "function" || !(element.attributes instanceof NamedNodeMap) || typeof element.removeAttribute !== "function" || typeof element.setAttribute !== "function" || typeof element.namespaceURI !== "string" || typeof element.insertBefore !== "function" || typeof element.hasChildNodes !== "function");
|
||||
const realTagName = getNodeName ? getNodeName(element) : null;
|
||||
if (typeof realTagName !== "string") {
|
||||
return false;
|
||||
}
|
||||
if (transformCaseFunc(realTagName) !== "form") {
|
||||
return false;
|
||||
}
|
||||
return typeof element.nodeName !== "string" || typeof element.textContent !== "string" || typeof element.removeChild !== "function" || // Realm-safe NamedNodeMap detection: equality against the cached
|
||||
// prototype getter. Clobbered .attributes (e.g. <input name="attributes">)
|
||||
// makes the direct read diverge from the cached read; a clean form
|
||||
// (same-realm OR foreign-realm) has both reads pointing at the same
|
||||
// canonical NamedNodeMap.
|
||||
element.attributes !== getAttributes(element) || typeof element.removeAttribute !== "function" || typeof element.setAttribute !== "function" || typeof element.namespaceURI !== "string" || typeof element.insertBefore !== "function" || typeof element.hasChildNodes !== "function" || // NodeType clobbering probe. Cached Node.prototype.nodeType getter
|
||||
// returns the integer 1 for any Element regardless of realm; direct
|
||||
// read on a clobbered form (e.g. <input name="nodeType">) returns
|
||||
// the named child element. Cheap addition — nodeType is read from
|
||||
// an internal slot, no serialization cost — and removes a residual
|
||||
// clobbering surface used by several mXSS / PI / comment branches
|
||||
// in _sanitizeElements that compare currentNode.nodeType directly.
|
||||
element.nodeType !== getNodeType(element) || // HTMLFormElement has [LegacyOverrideBuiltIns]: a descendant named
|
||||
// "childNodes" shadows the prototype getter. Direct reads of
|
||||
// form.childNodes from a clobbered form return the named child
|
||||
// instead of the real NodeList, so any walk that reads it directly
|
||||
// skips the form's real children. Compare the direct read to the
|
||||
// cached Node.prototype getter — when the form's named-property
|
||||
// getter intercepts the read, the two values differ and we flag
|
||||
// the form. This catches every clobbering child type (input,
|
||||
// select, etc.) regardless of whether the named child happens to
|
||||
// carry a numeric .length, which a typeof-based probe would miss
|
||||
// (e.g. HTMLSelectElement.length is a defined unsigned-long).
|
||||
element.childNodes !== getChildNodes(element);
|
||||
};
|
||||
const _isDocumentFragment = function _isDocumentFragment2(value) {
|
||||
if (!getNodeType || typeof value !== "object" || value === null) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
return getNodeType(value) === NODE_TYPE.documentFragment;
|
||||
} catch (_) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
const _isNode = function _isNode2(value) {
|
||||
if (!getNodeType || typeof value !== "object" || value === null) {
|
||||
@@ -1456,74 +1712,80 @@ function createDOMPurify() {
|
||||
}
|
||||
};
|
||||
function _executeHooks(hooks2, currentNode, data) {
|
||||
if (hooks2.length === 0) {
|
||||
return;
|
||||
}
|
||||
arrayForEach(hooks2, (hook) => {
|
||||
hook.call(DOMPurify, currentNode, data, CONFIG);
|
||||
});
|
||||
}
|
||||
const _isUnsafeNode = function _isUnsafeNode2(currentNode, tagName) {
|
||||
if (SAFE_FOR_XML && currentNode.hasChildNodes() && !_isNode(currentNode.firstElementChild) && regExpTest(ELEMENT_MARKUP_PROBE, currentNode.textContent) && regExpTest(ELEMENT_MARKUP_PROBE, currentNode.innerHTML)) {
|
||||
return true;
|
||||
}
|
||||
if (SAFE_FOR_XML && currentNode.namespaceURI === HTML_NAMESPACE && tagName === "style" && _isNode(currentNode.firstElementChild)) {
|
||||
return true;
|
||||
}
|
||||
if (currentNode.nodeType === NODE_TYPE.processingInstruction) {
|
||||
return true;
|
||||
}
|
||||
if (SAFE_FOR_XML && currentNode.nodeType === NODE_TYPE.comment && regExpTest(COMMENT_MARKUP_PROBE, currentNode.data)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
const _sanitizeDisallowedNode = function _sanitizeDisallowedNode2(currentNode, tagName) {
|
||||
if (!FORBID_TAGS[tagName] && _isBasicCustomElement(tagName)) {
|
||||
if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, tagName)) {
|
||||
return false;
|
||||
}
|
||||
if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(tagName)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (KEEP_CONTENT && !FORBID_CONTENTS[tagName]) {
|
||||
const parentNode = getParentNode(currentNode);
|
||||
const childNodes = getChildNodes(currentNode);
|
||||
if (childNodes && parentNode) {
|
||||
const childCount = childNodes.length;
|
||||
for (let i = childCount - 1; i >= 0; --i) {
|
||||
const hoisted = IN_PLACE ? childNodes[i] : cloneNode(childNodes[i], true);
|
||||
parentNode.insertBefore(hoisted, getNextSibling(currentNode));
|
||||
}
|
||||
}
|
||||
}
|
||||
_forceRemove(currentNode);
|
||||
return true;
|
||||
};
|
||||
const _sanitizeElements = function _sanitizeElements2(currentNode) {
|
||||
let content = null;
|
||||
_executeHooks(hooks.beforeSanitizeElements, currentNode, null);
|
||||
if (_isClobbered(currentNode)) {
|
||||
_forceRemove(currentNode);
|
||||
return true;
|
||||
}
|
||||
const tagName = transformCaseFunc(currentNode.nodeName);
|
||||
const tagName = transformCaseFunc(getNodeName ? getNodeName(currentNode) : currentNode.nodeName);
|
||||
_executeHooks(hooks.uponSanitizeElement, currentNode, {
|
||||
tagName,
|
||||
allowedTags: ALLOWED_TAGS
|
||||
});
|
||||
if (SAFE_FOR_XML && currentNode.hasChildNodes() && !_isNode(currentNode.firstElementChild) && regExpTest(/<[/\w!]/g, currentNode.innerHTML) && regExpTest(/<[/\w!]/g, currentNode.textContent)) {
|
||||
_forceRemove(currentNode);
|
||||
return true;
|
||||
}
|
||||
if (SAFE_FOR_XML && currentNode.namespaceURI === HTML_NAMESPACE && tagName === "style" && _isNode(currentNode.firstElementChild)) {
|
||||
_forceRemove(currentNode);
|
||||
return true;
|
||||
}
|
||||
if (currentNode.nodeType === NODE_TYPE.progressingInstruction) {
|
||||
_forceRemove(currentNode);
|
||||
return true;
|
||||
}
|
||||
if (SAFE_FOR_XML && currentNode.nodeType === NODE_TYPE.comment && regExpTest(/<[/\w]/g, currentNode.data)) {
|
||||
if (_isUnsafeNode(currentNode, tagName)) {
|
||||
_forceRemove(currentNode);
|
||||
return true;
|
||||
}
|
||||
if (FORBID_TAGS[tagName] || !(EXTRA_ELEMENT_HANDLING.tagCheck instanceof Function && EXTRA_ELEMENT_HANDLING.tagCheck(tagName)) && !ALLOWED_TAGS[tagName]) {
|
||||
if (!FORBID_TAGS[tagName] && _isBasicCustomElement(tagName)) {
|
||||
if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, tagName)) {
|
||||
return false;
|
||||
}
|
||||
if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(tagName)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (KEEP_CONTENT && !FORBID_CONTENTS[tagName]) {
|
||||
const parentNode = getParentNode(currentNode) || currentNode.parentNode;
|
||||
const childNodes = getChildNodes(currentNode) || currentNode.childNodes;
|
||||
if (childNodes && parentNode) {
|
||||
const childCount = childNodes.length;
|
||||
for (let i = childCount - 1; i >= 0; --i) {
|
||||
const childClone = cloneNode(childNodes[i], true);
|
||||
parentNode.insertBefore(childClone, getNextSibling(currentNode));
|
||||
}
|
||||
}
|
||||
}
|
||||
return _sanitizeDisallowedNode(currentNode, tagName);
|
||||
}
|
||||
const nt = getNodeType ? getNodeType(currentNode) : currentNode.nodeType;
|
||||
if (nt === NODE_TYPE.element && !_checkValidNamespace(currentNode)) {
|
||||
_forceRemove(currentNode);
|
||||
return true;
|
||||
}
|
||||
if (currentNode instanceof Element && !_checkValidNamespace(currentNode)) {
|
||||
_forceRemove(currentNode);
|
||||
return true;
|
||||
}
|
||||
if ((tagName === "noscript" || tagName === "noembed" || tagName === "noframes") && regExpTest(/<\/no(script|embed|frames)/i, currentNode.innerHTML)) {
|
||||
if ((tagName === "noscript" || tagName === "noembed" || tagName === "noframes") && regExpTest(FALLBACK_TAG_CLOSE, currentNode.innerHTML)) {
|
||||
_forceRemove(currentNode);
|
||||
return true;
|
||||
}
|
||||
if (SAFE_FOR_TEMPLATES && currentNode.nodeType === NODE_TYPE.text) {
|
||||
content = currentNode.textContent;
|
||||
arrayForEach([MUSTACHE_EXPR$1, ERB_EXPR$1, TMPLIT_EXPR$1], (expr) => {
|
||||
content = stringReplace(content, expr, " ");
|
||||
});
|
||||
const content = _stripTemplateExpressions(currentNode.textContent);
|
||||
if (currentNode.textContent !== content) {
|
||||
arrayPush(DOMPurify.removed, {
|
||||
element: currentNode.cloneNode()
|
||||
@@ -1542,9 +1804,9 @@ function createDOMPurify() {
|
||||
return false;
|
||||
}
|
||||
const nameIsPermitted = ALLOWED_ATTR[lcName] || EXTRA_ELEMENT_HANDLING.attributeCheck instanceof Function && EXTRA_ELEMENT_HANDLING.attributeCheck(lcName, lcTag);
|
||||
if (ALLOW_DATA_ATTR && !FORBID_ATTR[lcName] && regExpTest(DATA_ATTR$1, lcName)) ;
|
||||
if (ALLOW_DATA_ATTR && regExpTest(DATA_ATTR$1, lcName)) ;
|
||||
else if (ALLOW_ARIA_ATTR && regExpTest(ARIA_ATTR$1, lcName)) ;
|
||||
else if (!nameIsPermitted || FORBID_ATTR[lcName]) {
|
||||
else if (!nameIsPermitted) {
|
||||
if (
|
||||
// First condition does a very basic check if a) it's basically a valid custom element tagname AND
|
||||
// b) if the tagName passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck
|
||||
@@ -1569,6 +1831,35 @@ function createDOMPurify() {
|
||||
const _isBasicCustomElement = function _isBasicCustomElement2(tagName) {
|
||||
return !RESERVED_CUSTOM_ELEMENT_NAMES[stringToLowerCase(tagName)] && regExpTest(CUSTOM_ELEMENT$1, tagName);
|
||||
};
|
||||
const _applyTrustedTypesToAttribute = function _applyTrustedTypesToAttribute2(lcTag, lcName, namespaceURI, value) {
|
||||
if (trustedTypesPolicy && typeof trustedTypes === "object" && typeof trustedTypes.getAttributeType === "function" && !namespaceURI) {
|
||||
switch (trustedTypes.getAttributeType(lcTag, lcName)) {
|
||||
case "TrustedHTML": {
|
||||
return _createTrustedHTML(value);
|
||||
}
|
||||
case "TrustedScriptURL": {
|
||||
return _createTrustedScriptURL(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
return value;
|
||||
};
|
||||
const _setAttributeValue = function _setAttributeValue2(currentNode, name, namespaceURI, value) {
|
||||
try {
|
||||
if (namespaceURI) {
|
||||
currentNode.setAttributeNS(namespaceURI, name, value);
|
||||
} else {
|
||||
currentNode.setAttribute(name, value);
|
||||
}
|
||||
if (_isClobbered(currentNode)) {
|
||||
_forceRemove(currentNode);
|
||||
} else {
|
||||
arrayPop(DOMPurify.removed);
|
||||
}
|
||||
} catch (_) {
|
||||
_removeAttribute(name, currentNode);
|
||||
}
|
||||
};
|
||||
const _sanitizeAttributes = function _sanitizeAttributes2(currentNode) {
|
||||
_executeHooks(hooks.beforeSanitizeAttributes, currentNode, null);
|
||||
const attributes = currentNode.attributes;
|
||||
@@ -1583,6 +1874,7 @@ function createDOMPurify() {
|
||||
forceKeepAttr: void 0
|
||||
};
|
||||
let l = attributes.length;
|
||||
const lcTag = transformCaseFunc(currentNode.nodeName);
|
||||
while (l--) {
|
||||
const attr = attributes[l];
|
||||
const name = attr.name, namespaceURI = attr.namespaceURI, attrValue = attr.value;
|
||||
@@ -1614,50 +1906,20 @@ function createDOMPurify() {
|
||||
_removeAttribute(name, currentNode);
|
||||
continue;
|
||||
}
|
||||
if (!ALLOW_SELF_CLOSE_IN_ATTR && regExpTest(/\/>/i, value)) {
|
||||
if (!ALLOW_SELF_CLOSE_IN_ATTR && regExpTest(SELF_CLOSING_TAG, value)) {
|
||||
_removeAttribute(name, currentNode);
|
||||
continue;
|
||||
}
|
||||
if (SAFE_FOR_TEMPLATES) {
|
||||
arrayForEach([MUSTACHE_EXPR$1, ERB_EXPR$1, TMPLIT_EXPR$1], (expr) => {
|
||||
value = stringReplace(value, expr, " ");
|
||||
});
|
||||
value = _stripTemplateExpressions(value);
|
||||
}
|
||||
const lcTag = transformCaseFunc(currentNode.nodeName);
|
||||
if (!_isValidAttribute(lcTag, lcName, value)) {
|
||||
_removeAttribute(name, currentNode);
|
||||
continue;
|
||||
}
|
||||
if (trustedTypesPolicy && typeof trustedTypes === "object" && typeof trustedTypes.getAttributeType === "function") {
|
||||
if (namespaceURI) ;
|
||||
else {
|
||||
switch (trustedTypes.getAttributeType(lcTag, lcName)) {
|
||||
case "TrustedHTML": {
|
||||
value = trustedTypesPolicy.createHTML(value);
|
||||
break;
|
||||
}
|
||||
case "TrustedScriptURL": {
|
||||
value = trustedTypesPolicy.createScriptURL(value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
value = _applyTrustedTypesToAttribute(lcTag, lcName, namespaceURI, value);
|
||||
if (value !== initValue) {
|
||||
try {
|
||||
if (namespaceURI) {
|
||||
currentNode.setAttributeNS(namespaceURI, name, value);
|
||||
} else {
|
||||
currentNode.setAttribute(name, value);
|
||||
}
|
||||
if (_isClobbered(currentNode)) {
|
||||
_forceRemove(currentNode);
|
||||
} else {
|
||||
arrayPop(DOMPurify.removed);
|
||||
}
|
||||
} catch (_) {
|
||||
_removeAttribute(name, currentNode);
|
||||
}
|
||||
_setAttributeValue(currentNode, name, namespaceURI, value);
|
||||
}
|
||||
}
|
||||
_executeHooks(hooks.afterSanitizeAttributes, currentNode, null);
|
||||
@@ -1670,28 +1932,67 @@ function createDOMPurify() {
|
||||
_executeHooks(hooks.uponSanitizeShadowNode, shadowNode, null);
|
||||
_sanitizeElements(shadowNode);
|
||||
_sanitizeAttributes(shadowNode);
|
||||
if (shadowNode.content instanceof DocumentFragment) {
|
||||
if (_isDocumentFragment(shadowNode.content)) {
|
||||
_sanitizeShadowDOM2(shadowNode.content);
|
||||
}
|
||||
const shadowNodeType = getNodeType ? getNodeType(shadowNode) : shadowNode.nodeType;
|
||||
if (shadowNodeType === NODE_TYPE.element) {
|
||||
const innerSr = getShadowRoot(shadowNode);
|
||||
if (_isDocumentFragment(innerSr)) {
|
||||
_sanitizeAttachedShadowRoots(innerSr);
|
||||
_sanitizeShadowDOM2(innerSr);
|
||||
}
|
||||
}
|
||||
}
|
||||
_executeHooks(hooks.afterSanitizeShadowDOM, fragment, null);
|
||||
};
|
||||
const _sanitizeAttachedShadowRoots2 = function _sanitizeAttachedShadowRoots(root) {
|
||||
if (root.nodeType === NODE_TYPE.element && root.shadowRoot instanceof DocumentFragment) {
|
||||
const sr = root.shadowRoot;
|
||||
_sanitizeAttachedShadowRoots2(sr);
|
||||
_sanitizeShadowDOM2(sr);
|
||||
}
|
||||
const childNodes = root.childNodes;
|
||||
if (!childNodes) {
|
||||
return;
|
||||
}
|
||||
const snapshot = [];
|
||||
arrayForEach(childNodes, (child) => {
|
||||
arrayPush(snapshot, child);
|
||||
});
|
||||
for (const child of snapshot) {
|
||||
_sanitizeAttachedShadowRoots2(child);
|
||||
const _sanitizeAttachedShadowRoots = function _sanitizeAttachedShadowRoots2(root) {
|
||||
const stack = [{
|
||||
node: root,
|
||||
shadow: null
|
||||
}];
|
||||
while (stack.length > 0) {
|
||||
const item = stack.pop();
|
||||
if (item.shadow) {
|
||||
_sanitizeShadowDOM2(item.shadow);
|
||||
continue;
|
||||
}
|
||||
const node = item.node;
|
||||
const nodeType = getNodeType ? getNodeType(node) : node.nodeType;
|
||||
const isElement = nodeType === NODE_TYPE.element;
|
||||
const childNodes = getChildNodes(node);
|
||||
if (childNodes) {
|
||||
for (let i = childNodes.length - 1; i >= 0; --i) {
|
||||
stack.push({
|
||||
node: childNodes[i],
|
||||
shadow: null
|
||||
});
|
||||
}
|
||||
}
|
||||
if (isElement) {
|
||||
const rootName = getNodeName ? getNodeName(node) : null;
|
||||
if (typeof rootName === "string" && transformCaseFunc(rootName) === "template") {
|
||||
const content = node.content;
|
||||
if (_isDocumentFragment(content)) {
|
||||
stack.push({
|
||||
node: content,
|
||||
shadow: null
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isElement) {
|
||||
const sr = getShadowRoot(node);
|
||||
if (_isDocumentFragment(sr)) {
|
||||
stack.push({
|
||||
node: null,
|
||||
shadow: sr
|
||||
}, {
|
||||
node: sr,
|
||||
shadow: null
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
DOMPurify.sanitize = function(dirty) {
|
||||
@@ -1717,18 +2018,24 @@ function createDOMPurify() {
|
||||
_parseConfig(cfg);
|
||||
}
|
||||
DOMPurify.removed = [];
|
||||
if (typeof dirty === "string") {
|
||||
IN_PLACE = false;
|
||||
}
|
||||
if (IN_PLACE) {
|
||||
const nn = dirty.nodeName;
|
||||
const inPlace = IN_PLACE && typeof dirty !== "string" && _isNode(dirty);
|
||||
if (inPlace) {
|
||||
const nn = getNodeName ? getNodeName(dirty) : dirty.nodeName;
|
||||
if (typeof nn === "string") {
|
||||
const tagName = transformCaseFunc(nn);
|
||||
if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) {
|
||||
throw typeErrorCreate("root node is forbidden and cannot be sanitized in-place");
|
||||
}
|
||||
}
|
||||
_sanitizeAttachedShadowRoots2(dirty);
|
||||
if (_isClobbered(dirty)) {
|
||||
throw typeErrorCreate("root node is clobbered and cannot be sanitized in-place");
|
||||
}
|
||||
try {
|
||||
_sanitizeAttachedShadowRoots(dirty);
|
||||
} catch (error) {
|
||||
_neutralizeRoot(dirty);
|
||||
throw error;
|
||||
}
|
||||
} else if (_isNode(dirty)) {
|
||||
body = _initDocument("<!---->");
|
||||
importedNode = body.ownerDocument.importNode(dirty, true);
|
||||
@@ -1739,11 +2046,11 @@ function createDOMPurify() {
|
||||
} else {
|
||||
body.appendChild(importedNode);
|
||||
}
|
||||
_sanitizeAttachedShadowRoots2(importedNode);
|
||||
_sanitizeAttachedShadowRoots(importedNode);
|
||||
} else {
|
||||
if (!RETURN_DOM && !SAFE_FOR_TEMPLATES && !WHOLE_DOCUMENT && // eslint-disable-next-line unicorn/prefer-includes
|
||||
dirty.indexOf("<") === -1) {
|
||||
return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML(dirty) : dirty;
|
||||
return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? _createTrustedHTML(dirty) : dirty;
|
||||
}
|
||||
body = _initDocument(dirty);
|
||||
if (!body) {
|
||||
@@ -1753,23 +2060,35 @@ function createDOMPurify() {
|
||||
if (body && FORCE_BODY) {
|
||||
_forceRemove(body.firstChild);
|
||||
}
|
||||
const nodeIterator = _createNodeIterator(IN_PLACE ? dirty : body);
|
||||
while (currentNode = nodeIterator.nextNode()) {
|
||||
_sanitizeElements(currentNode);
|
||||
_sanitizeAttributes(currentNode);
|
||||
if (currentNode.content instanceof DocumentFragment) {
|
||||
_sanitizeShadowDOM2(currentNode.content);
|
||||
const nodeIterator = _createNodeIterator(inPlace ? dirty : body);
|
||||
try {
|
||||
while (currentNode = nodeIterator.nextNode()) {
|
||||
_sanitizeElements(currentNode);
|
||||
_sanitizeAttributes(currentNode);
|
||||
if (_isDocumentFragment(currentNode.content)) {
|
||||
_sanitizeShadowDOM2(currentNode.content);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
if (inPlace) {
|
||||
_neutralizeRoot(dirty);
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
if (IN_PLACE) {
|
||||
if (inPlace) {
|
||||
arrayForEach(DOMPurify.removed, (entry) => {
|
||||
if (entry.element) {
|
||||
_neutralizeSubtree(entry.element);
|
||||
}
|
||||
});
|
||||
if (SAFE_FOR_TEMPLATES) {
|
||||
_scrubTemplateExpressions(dirty);
|
||||
_scrubTemplateExpressions2(dirty);
|
||||
}
|
||||
return dirty;
|
||||
}
|
||||
if (RETURN_DOM) {
|
||||
if (SAFE_FOR_TEMPLATES) {
|
||||
_scrubTemplateExpressions(body);
|
||||
_scrubTemplateExpressions2(body);
|
||||
}
|
||||
if (RETURN_DOM_FRAGMENT) {
|
||||
returnNode = createDocumentFragment.call(body.ownerDocument);
|
||||
@@ -1789,11 +2108,9 @@ function createDOMPurify() {
|
||||
serializedHTML = "<!DOCTYPE " + body.ownerDocument.doctype.name + ">\n" + serializedHTML;
|
||||
}
|
||||
if (SAFE_FOR_TEMPLATES) {
|
||||
arrayForEach([MUSTACHE_EXPR$1, ERB_EXPR$1, TMPLIT_EXPR$1], (expr) => {
|
||||
serializedHTML = stringReplace(serializedHTML, expr, " ");
|
||||
});
|
||||
serializedHTML = _stripTemplateExpressions(serializedHTML);
|
||||
}
|
||||
return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML(serializedHTML) : serializedHTML;
|
||||
return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? _createTrustedHTML(serializedHTML) : serializedHTML;
|
||||
};
|
||||
DOMPurify.setConfig = function() {
|
||||
let cfg = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {};
|
||||
@@ -1803,6 +2120,8 @@ function createDOMPurify() {
|
||||
DOMPurify.clearConfig = function() {
|
||||
CONFIG = null;
|
||||
SET_CONFIG = false;
|
||||
trustedTypesPolicy = defaultTrustedTypesPolicy;
|
||||
emptyHTML = "";
|
||||
};
|
||||
DOMPurify.isValidAttribute = function(tag, attr, value) {
|
||||
if (!CONFIG) {
|
||||
@@ -2592,13 +2911,8 @@ var EnhancedSecureCryptoUtils = class _EnhancedSecureCryptoUtils {
|
||||
if (this.isProductionMode) {
|
||||
if (level === "error") {
|
||||
console.error(`\u274C [SecureChat] ${message} [ERROR_CODE: ${this._generateErrorCode(message)}]`);
|
||||
if (context && Object.keys(context).length > 0) {
|
||||
console.error("Error details:", context);
|
||||
}
|
||||
} else if (level === "warn") {
|
||||
console.warn(`\u26A0\uFE0F [SecureChat] ${message}`);
|
||||
} else if (level === "info" || level === "debug") {
|
||||
console.log(`[SecureChat] ${message}`, context);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
@@ -3883,7 +4197,7 @@ var EnhancedSecureCryptoUtils = class _EnhancedSecureCryptoUtils {
|
||||
// src/transfer/EnhancedSecureFileTransfer.js
|
||||
var SecureFileTransferContext = class _SecureFileTransferContext {
|
||||
static #instance = null;
|
||||
static #contextKey = Symbol("SecureFileTransferContext");
|
||||
static #contextKey = /* @__PURE__ */ Symbol("SecureFileTransferContext");
|
||||
static getInstance() {
|
||||
if (!this.#instance) {
|
||||
this.#instance = new _SecureFileTransferContext();
|
||||
@@ -17167,7 +17481,7 @@ Right-click or Ctrl+click to disconnect`,
|
||||
React.createElement("p", {
|
||||
key: "subtitle",
|
||||
className: "text-xs sm:text-sm text-muted hidden sm:block"
|
||||
}, "End-to-end freedom v4.8.5")
|
||||
}, "End-to-end freedom v4.8.9")
|
||||
])
|
||||
]),
|
||||
// Status and Controls - Responsive
|
||||
@@ -18793,6 +19107,6 @@ if (document.readyState === "loading") {
|
||||
/*! Bundled license information:
|
||||
|
||||
dompurify/dist/purify.es.mjs:
|
||||
(*! @license DOMPurify 3.4.4 | (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.4/LICENSE *)
|
||||
(*! @license DOMPurify 3.4.10 | (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.10/LICENSE *)
|
||||
*/
|
||||
//# sourceMappingURL=app-boot.js.map
|
||||
|
||||
Vendored
+3
-3
File diff suppressed because one or more lines are too long
Vendored
+1
-1
@@ -1820,7 +1820,7 @@ var EnhancedSecureP2PChat = () => {
|
||||
} catch (error) {
|
||||
}
|
||||
}
|
||||
handleMessage(" SecureBit.chat Enhanced Security Edition v4.8.7 - ECDH + DTLS + SAS initialized. Ready to establish a secure connection with ECDH key exchange, DTLS fingerprint verification, and SAS authentication to prevent MITM attacks.", "system");
|
||||
handleMessage(" SecureBit.chat Enhanced Security Edition v4.8.9 - ECDH + DTLS + SAS initialized. Ready to establish a secure connection with ECDH key exchange, DTLS fingerprint verification, and SAS authentication to prevent MITM attacks.", "system");
|
||||
const handleBeforeUnload = (event) => {
|
||||
if (event.type === "beforeunload" && !isTabSwitching) {
|
||||
if (webrtcManagerRef.current && webrtcManagerRef.current.isConnected()) {
|
||||
|
||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+5
-1
@@ -5,7 +5,11 @@ var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __commonJS = (cb, mod) => function __require() {
|
||||
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
||||
try {
|
||||
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
||||
} catch (e) {
|
||||
throw mod = 0, e;
|
||||
}
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
|
||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user