mini-program-cljs
Version:
1 lines • 78.9 kB
JavaScript
["^ ","~:resource-id",["~:shadow.build.classpath/resource","goog/html/safeurl.js"],"~:js","goog.provide(\"goog.html.SafeUrl\");\ngoog.require(\"goog.asserts\");\ngoog.require(\"goog.fs.url\");\ngoog.require(\"goog.html.TrustedResourceUrl\");\ngoog.require(\"goog.i18n.bidi.Dir\");\ngoog.require(\"goog.i18n.bidi.DirectionalString\");\ngoog.require(\"goog.string.Const\");\ngoog.require(\"goog.string.TypedString\");\ngoog.require(\"goog.string.internal\");\n/**\n * @final\n * @struct\n * @constructor\n * @implements {goog.i18n.bidi.DirectionalString}\n * @implements {goog.string.TypedString}\n * @param {!Object=} opt_token\n * @param {string=} opt_content\n */\ngoog.html.SafeUrl = function(opt_token, opt_content) {\n /** @private @type {string} */ this.privateDoNotAccessOrElseSafeUrlWrappedValue_ = opt_token === goog.html.SafeUrl.CONSTRUCTOR_TOKEN_PRIVATE_ && opt_content || \"\";\n /** @private @const @type {!Object} */ this.SAFE_URL_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ = goog.html.SafeUrl.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_;\n};\n/** @const @type {string} */ goog.html.SafeUrl.INNOCUOUS_STRING = \"about:invalid#zClosurez\";\n/** @const @override */ goog.html.SafeUrl.prototype.implementsGoogStringTypedString = true;\n/** @override */ goog.html.SafeUrl.prototype.getTypedStringValue = function() {\n return this.privateDoNotAccessOrElseSafeUrlWrappedValue_.toString();\n};\n/** @const @override */ goog.html.SafeUrl.prototype.implementsGoogI18nBidiDirectionalString = true;\n/** @override */ goog.html.SafeUrl.prototype.getDirection = function() {\n return goog.i18n.bidi.Dir.LTR;\n};\nif (goog.DEBUG) {\n /** @override */ goog.html.SafeUrl.prototype.toString = function() {\n return \"SafeUrl{\" + this.privateDoNotAccessOrElseSafeUrlWrappedValue_ + \"}\";\n };\n}\n/**\n * @param {!goog.html.SafeUrl} safeUrl\n * @return {string}\n */\ngoog.html.SafeUrl.unwrap = function(safeUrl) {\n if (safeUrl instanceof goog.html.SafeUrl && safeUrl.constructor === goog.html.SafeUrl && safeUrl.SAFE_URL_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ === goog.html.SafeUrl.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_) {\n return safeUrl.privateDoNotAccessOrElseSafeUrlWrappedValue_;\n } else {\n goog.asserts.fail(\"expected object of type SafeUrl, got '\" + safeUrl + \"' of type \" + goog.typeOf(safeUrl));\n return \"type_error:SafeUrl\";\n }\n};\n/**\n * @param {!goog.string.Const} url\n * @return {!goog.html.SafeUrl}\n */\ngoog.html.SafeUrl.fromConstant = function(url) {\n return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(goog.string.Const.unwrap(url));\n};\n/** @private @const */ goog.html.SAFE_MIME_TYPE_PATTERN_ = new RegExp(\"^(?:audio/(?:3gpp2|3gpp|aac|L16|midi|mp3|mp4|mpeg|oga|ogg|opus|x-m4a|x-wav|wav|webm)|\" + \"image/(?:bmp|gif|jpeg|jpg|png|tiff|webp|x-icon)|\" + \"text/csv|\" + \"video/(?:mpeg|mp4|ogg|webm|quicktime))\" + '(?:;\\\\w+\\x3d(?:\\\\w+|\"[\\\\w;\\x3d]+\"))*$', \"i\");\n/**\n * @param {string} mimeType\n * @return {boolean}\n */\ngoog.html.SafeUrl.isSafeMimeType = function(mimeType) {\n return goog.html.SAFE_MIME_TYPE_PATTERN_.test(mimeType);\n};\n/**\n * @param {!Blob} blob\n * @return {!goog.html.SafeUrl}\n */\ngoog.html.SafeUrl.fromBlob = function(blob) {\n var url = goog.html.SAFE_MIME_TYPE_PATTERN_.test(blob.type) ? goog.fs.url.createObjectUrl(blob) : goog.html.SafeUrl.INNOCUOUS_STRING;\n return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(url);\n};\n/** @private @const */ goog.html.DATA_URL_PATTERN_ = /^data:([^,]*);base64,[a-z0-9+\\/]+=*$/i;\n/**\n * @param {string} dataUrl\n * @return {!goog.html.SafeUrl}\n */\ngoog.html.SafeUrl.fromDataUrl = function(dataUrl) {\n var filteredDataUrl = dataUrl.replace(/(%0A|%0D)/g, \"\");\n var match = filteredDataUrl.match(goog.html.DATA_URL_PATTERN_);\n var valid = match && goog.html.SAFE_MIME_TYPE_PATTERN_.test(match[1]);\n return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(valid ? filteredDataUrl : goog.html.SafeUrl.INNOCUOUS_STRING);\n};\n/**\n * @param {string} telUrl\n * @return {!goog.html.SafeUrl}\n */\ngoog.html.SafeUrl.fromTelUrl = function(telUrl) {\n if (!goog.string.internal.caseInsensitiveStartsWith(telUrl, \"tel:\")) {\n telUrl = goog.html.SafeUrl.INNOCUOUS_STRING;\n }\n return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(telUrl);\n};\n/** @private @const */ goog.html.SIP_URL_PATTERN_ = new RegExp(\"^sip[s]?:[+a-z0-9_.!$%\\x26'*\\\\/\\x3d^`{|}~-]+@([a-z0-9-]+\\\\.)+[a-z0-9]{2,63}$\", \"i\");\n/**\n * @param {string} sipUrl\n * @return {!goog.html.SafeUrl}\n */\ngoog.html.SafeUrl.fromSipUrl = function(sipUrl) {\n if (!goog.html.SIP_URL_PATTERN_.test(decodeURIComponent(sipUrl))) {\n sipUrl = goog.html.SafeUrl.INNOCUOUS_STRING;\n }\n return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(sipUrl);\n};\n/**\n * @param {string} facebookMessengerUrl\n * @return {!goog.html.SafeUrl}\n */\ngoog.html.SafeUrl.fromFacebookMessengerUrl = function(facebookMessengerUrl) {\n if (!goog.string.internal.caseInsensitiveStartsWith(facebookMessengerUrl, \"fb-messenger://share\")) {\n facebookMessengerUrl = goog.html.SafeUrl.INNOCUOUS_STRING;\n }\n return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(facebookMessengerUrl);\n};\n/**\n * @param {string} whatsAppUrl\n * @return {!goog.html.SafeUrl}\n */\ngoog.html.SafeUrl.fromWhatsAppUrl = function(whatsAppUrl) {\n if (!goog.string.internal.caseInsensitiveStartsWith(whatsAppUrl, \"whatsapp://send\")) {\n whatsAppUrl = goog.html.SafeUrl.INNOCUOUS_STRING;\n }\n return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(whatsAppUrl);\n};\n/**\n * @param {string} smsUrl\n * @return {!goog.html.SafeUrl}\n */\ngoog.html.SafeUrl.fromSmsUrl = function(smsUrl) {\n if (!goog.string.internal.caseInsensitiveStartsWith(smsUrl, \"sms:\") || !goog.html.SafeUrl.isSmsUrlBodyValid_(smsUrl)) {\n smsUrl = goog.html.SafeUrl.INNOCUOUS_STRING;\n }\n return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(smsUrl);\n};\n/**\n * @private\n * @param {string} smsUrl\n * @return {boolean}\n */\ngoog.html.SafeUrl.isSmsUrlBodyValid_ = function(smsUrl) {\n var hash = smsUrl.indexOf(\"#\");\n if (hash > 0) {\n smsUrl = smsUrl.substring(0, hash);\n }\n var bodyParams = smsUrl.match(/[?&]body=/gi);\n if (!bodyParams) {\n return true;\n }\n if (bodyParams.length > 1) {\n return false;\n }\n var bodyValue = smsUrl.match(/[?&]body=([^&]*)/)[1];\n if (!bodyValue) {\n return true;\n }\n try {\n decodeURIComponent(bodyValue);\n } catch (error) {\n return false;\n }\n return /^(?:[a-z0-9\\-_.~]|%[0-9a-f]{2})+$/i.test(bodyValue);\n};\n/**\n * @param {string} sshUrl\n * @return {!goog.html.SafeUrl}\n */\ngoog.html.SafeUrl.fromSshUrl = function(sshUrl) {\n if (!goog.string.internal.caseInsensitiveStartsWith(sshUrl, \"ssh://\")) {\n sshUrl = goog.html.SafeUrl.INNOCUOUS_STRING;\n }\n return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(sshUrl);\n};\n/**\n * @param {string} url\n * @param {(!goog.string.Const|!Array<!goog.string.Const>)} extensionId\n * @return {!goog.html.SafeUrl}\n */\ngoog.html.SafeUrl.sanitizeChromeExtensionUrl = function(url, extensionId) {\n return goog.html.SafeUrl.sanitizeExtensionUrl_(/^chrome-extension:\\/\\/([^\\/]+)\\//, url, extensionId);\n};\n/**\n * @param {string} url\n * @param {(!goog.string.Const|!Array<!goog.string.Const>)} extensionId\n * @return {!goog.html.SafeUrl}\n */\ngoog.html.SafeUrl.sanitizeFirefoxExtensionUrl = function(url, extensionId) {\n return goog.html.SafeUrl.sanitizeExtensionUrl_(/^moz-extension:\\/\\/([^\\/]+)\\//, url, extensionId);\n};\n/**\n * @param {string} url\n * @param {(!goog.string.Const|!Array<!goog.string.Const>)} extensionId\n * @return {!goog.html.SafeUrl}\n */\ngoog.html.SafeUrl.sanitizeEdgeExtensionUrl = function(url, extensionId) {\n return goog.html.SafeUrl.sanitizeExtensionUrl_(/^ms-browser-extension:\\/\\/([^\\/]+)\\//, url, extensionId);\n};\n/**\n * @private\n * @param {!RegExp} scheme\n * @param {string} url\n * @param {(!goog.string.Const|!Array<!goog.string.Const>)} extensionId\n * @return {!goog.html.SafeUrl}\n */\ngoog.html.SafeUrl.sanitizeExtensionUrl_ = function(scheme, url, extensionId) {\n var matches = scheme.exec(url);\n if (!matches) {\n url = goog.html.SafeUrl.INNOCUOUS_STRING;\n } else {\n var extractedExtensionId = matches[1];\n var acceptedExtensionIds;\n if (extensionId instanceof goog.string.Const) {\n acceptedExtensionIds = [goog.string.Const.unwrap(extensionId)];\n } else {\n acceptedExtensionIds = extensionId.map(function unwrap(x) {\n return goog.string.Const.unwrap(x);\n });\n }\n if (acceptedExtensionIds.indexOf(extractedExtensionId) == -1) {\n url = goog.html.SafeUrl.INNOCUOUS_STRING;\n }\n }\n return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(url);\n};\n/**\n * @param {!goog.html.TrustedResourceUrl} trustedResourceUrl\n * @return {!goog.html.SafeUrl}\n */\ngoog.html.SafeUrl.fromTrustedResourceUrl = function(trustedResourceUrl) {\n return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(goog.html.TrustedResourceUrl.unwrap(trustedResourceUrl));\n};\n/** @private @const @type {!RegExp} */ goog.html.SAFE_URL_PATTERN_ = /^(?:(?:https?|mailto|ftp):|[^:/?#]*(?:[/?#]|$))/i;\n/** @const @type {!RegExp} */ goog.html.SafeUrl.SAFE_URL_PATTERN = goog.html.SAFE_URL_PATTERN_;\n/**\n * @param {(string|!goog.string.TypedString)} url\n * @return {!goog.html.SafeUrl}\n */\ngoog.html.SafeUrl.sanitize = function(url) {\n if (url instanceof goog.html.SafeUrl) {\n return url;\n } else {\n if (typeof url == \"object\" && url.implementsGoogStringTypedString) {\n url = /** @type {!goog.string.TypedString} */ (url).getTypedStringValue();\n } else {\n url = String(url);\n }\n }\n if (!goog.html.SAFE_URL_PATTERN_.test(url)) {\n url = goog.html.SafeUrl.INNOCUOUS_STRING;\n }\n return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(url);\n};\n/**\n * @param {(string|!goog.string.TypedString)} url\n * @param {boolean=} opt_allowDataUrl\n * @return {!goog.html.SafeUrl}\n */\ngoog.html.SafeUrl.sanitizeAssertUnchanged = function(url, opt_allowDataUrl) {\n if (url instanceof goog.html.SafeUrl) {\n return url;\n } else {\n if (typeof url == \"object\" && url.implementsGoogStringTypedString) {\n url = /** @type {!goog.string.TypedString} */ (url).getTypedStringValue();\n } else {\n url = String(url);\n }\n }\n if (opt_allowDataUrl && /^data:/i.test(url)) {\n var safeUrl = goog.html.SafeUrl.fromDataUrl(url);\n if (safeUrl.getTypedStringValue() == url) {\n return safeUrl;\n }\n }\n if (!goog.asserts.assert(goog.html.SAFE_URL_PATTERN_.test(url), \"%s does not match the safe URL pattern\", url)) {\n url = goog.html.SafeUrl.INNOCUOUS_STRING;\n }\n return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(url);\n};\n/** @private @const @type {!Object} */ goog.html.SafeUrl.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ = {};\n/**\n * @package\n * @param {string} url\n * @return {!goog.html.SafeUrl}\n */\ngoog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse = function(url) {\n return new goog.html.SafeUrl(goog.html.SafeUrl.CONSTRUCTOR_TOKEN_PRIVATE_, url);\n};\n/** @const @type {!goog.html.SafeUrl} */ goog.html.SafeUrl.ABOUT_BLANK = goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(\"about:blank\");\n/** @private @const @type {!Object} */ goog.html.SafeUrl.CONSTRUCTOR_TOKEN_PRIVATE_ = {};\n","~:source","// Copyright 2013 The Closure Library Authors. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS-IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n/**\n * @fileoverview The SafeUrl type and its builders.\n *\n * TODO(xtof): Link to document stating type contract.\n */\n\ngoog.provide('goog.html.SafeUrl');\n\ngoog.require('goog.asserts');\ngoog.require('goog.fs.url');\ngoog.require('goog.html.TrustedResourceUrl');\ngoog.require('goog.i18n.bidi.Dir');\ngoog.require('goog.i18n.bidi.DirectionalString');\ngoog.require('goog.string.Const');\ngoog.require('goog.string.TypedString');\ngoog.require('goog.string.internal');\n\n\n\n/**\n * A string that is safe to use in URL context in DOM APIs and HTML documents.\n *\n * A SafeUrl is a string-like object that carries the security type contract\n * that its value as a string will not cause untrusted script execution\n * when evaluated as a hyperlink URL in a browser.\n *\n * Values of this type are guaranteed to be safe to use in URL/hyperlink\n * contexts, such as assignment to URL-valued DOM properties, in the sense that\n * the use will not result in a Cross-Site-Scripting vulnerability. Similarly,\n * SafeUrls can be interpolated into the URL context of an HTML template (e.g.,\n * inside a href attribute). However, appropriate HTML-escaping must still be\n * applied.\n *\n * Note that, as documented in `goog.html.SafeUrl.unwrap`, this type's\n * contract does not guarantee that instances are safe to interpolate into HTML\n * without appropriate escaping.\n *\n * Note also that this type's contract does not imply any guarantees regarding\n * the resource the URL refers to. In particular, SafeUrls are <b>not</b>\n * safe to use in a context where the referred-to resource is interpreted as\n * trusted code, e.g., as the src of a script tag.\n *\n * Instances of this type must be created via the factory methods\n * (`goog.html.SafeUrl.fromConstant`, `goog.html.SafeUrl.sanitize`),\n * etc and not by invoking its constructor. The constructor is organized in a\n * way that only methods from that file can call it and initialize with\n * non-empty values. Anyone else calling constructor will get default instance\n * with empty value.\n *\n * @see goog.html.SafeUrl#fromConstant\n * @see goog.html.SafeUrl#from\n * @see goog.html.SafeUrl#sanitize\n * @constructor\n * @final\n * @struct\n * @implements {goog.i18n.bidi.DirectionalString}\n * @implements {goog.string.TypedString}\n * @param {!Object=} opt_token package-internal implementation detail.\n * @param {string=} opt_content package-internal implementation detail.\n */\ngoog.html.SafeUrl = function(opt_token, opt_content) {\n /**\n * The contained value of this SafeUrl. The field has a purposely ugly\n * name to make (non-compiled) code that attempts to directly access this\n * field stand out.\n * @private {string}\n */\n this.privateDoNotAccessOrElseSafeUrlWrappedValue_ =\n ((opt_token === goog.html.SafeUrl.CONSTRUCTOR_TOKEN_PRIVATE_) &&\n opt_content) ||\n '';\n\n /**\n * A type marker used to implement additional run-time type checking.\n * @see goog.html.SafeUrl#unwrap\n * @const {!Object}\n * @private\n */\n this.SAFE_URL_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ =\n goog.html.SafeUrl.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_;\n};\n\n\n/**\n * The innocuous string generated by goog.html.SafeUrl.sanitize when passed\n * an unsafe URL.\n *\n * about:invalid is registered in\n * http://www.w3.org/TR/css3-values/#about-invalid.\n * http://tools.ietf.org/html/rfc6694#section-2.2.1 permits about URLs to\n * contain a fragment, which is not to be considered when determining if an\n * about URL is well-known.\n *\n * Using about:invalid seems preferable to using a fixed data URL, since\n * browsers might choose to not report CSP violations on it, as legitimate\n * CSS function calls to attr() can result in this URL being produced. It is\n * also a standard URL which matches exactly the semantics we need:\n * \"The about:invalid URI references a non-existent document with a generic\n * error condition. It can be used when a URI is necessary, but the default\n * value shouldn't be resolveable as any type of document\".\n *\n * @const {string}\n */\ngoog.html.SafeUrl.INNOCUOUS_STRING = 'about:invalid#zClosurez';\n\n\n/**\n * @override\n * @const\n */\ngoog.html.SafeUrl.prototype.implementsGoogStringTypedString = true;\n\n\n/**\n * Returns this SafeUrl's value a string.\n *\n * IMPORTANT: In code where it is security relevant that an object's type is\n * indeed `SafeUrl`, use `goog.html.SafeUrl.unwrap` instead of this\n * method. If in doubt, assume that it's security relevant. In particular, note\n * that goog.html functions which return a goog.html type do not guarantee that\n * the returned instance is of the right type.\n *\n * IMPORTANT: The guarantees of the SafeUrl type contract only extend to the\n * behavior of browsers when interpreting URLs. Values of SafeUrl objects MUST\n * be appropriately escaped before embedding in a HTML document. Note that the\n * required escaping is context-sensitive (e.g. a different escaping is\n * required for embedding a URL in a style property within a style\n * attribute, as opposed to embedding in a href attribute).\n *\n * @see goog.html.SafeUrl#unwrap\n * @override\n */\ngoog.html.SafeUrl.prototype.getTypedStringValue = function() {\n return this.privateDoNotAccessOrElseSafeUrlWrappedValue_.toString();\n};\n\n\n/**\n * @override\n * @const\n */\ngoog.html.SafeUrl.prototype.implementsGoogI18nBidiDirectionalString = true;\n\n\n/**\n * Returns this URLs directionality, which is always `LTR`.\n * @override\n */\ngoog.html.SafeUrl.prototype.getDirection = function() {\n return goog.i18n.bidi.Dir.LTR;\n};\n\n\nif (goog.DEBUG) {\n /**\n * Returns a debug string-representation of this value.\n *\n * To obtain the actual string value wrapped in a SafeUrl, use\n * `goog.html.SafeUrl.unwrap`.\n *\n * @see goog.html.SafeUrl#unwrap\n * @override\n */\n goog.html.SafeUrl.prototype.toString = function() {\n return 'SafeUrl{' + this.privateDoNotAccessOrElseSafeUrlWrappedValue_ + '}';\n };\n}\n\n\n/**\n * Performs a runtime check that the provided object is indeed a SafeUrl\n * object, and returns its value.\n *\n * IMPORTANT: The guarantees of the SafeUrl type contract only extend to the\n * behavior of browsers when interpreting URLs. Values of SafeUrl objects MUST\n * be appropriately escaped before embedding in a HTML document. Note that the\n * required escaping is context-sensitive (e.g. a different escaping is\n * required for embedding a URL in a style property within a style\n * attribute, as opposed to embedding in a href attribute).\n *\n * @param {!goog.html.SafeUrl} safeUrl The object to extract from.\n * @return {string} The SafeUrl object's contained string, unless the run-time\n * type check fails. In that case, `unwrap` returns an innocuous\n * string, or, if assertions are enabled, throws\n * `goog.asserts.AssertionError`.\n */\ngoog.html.SafeUrl.unwrap = function(safeUrl) {\n // Perform additional Run-time type-checking to ensure that safeUrl is indeed\n // an instance of the expected type. This provides some additional protection\n // against security bugs due to application code that disables type checks.\n // Specifically, the following checks are performed:\n // 1. The object is an instance of the expected type.\n // 2. The object is not an instance of a subclass.\n // 3. The object carries a type marker for the expected type. \"Faking\" an\n // object requires a reference to the type marker, which has names intended\n // to stand out in code reviews.\n if (safeUrl instanceof goog.html.SafeUrl &&\n safeUrl.constructor === goog.html.SafeUrl &&\n safeUrl.SAFE_URL_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ ===\n goog.html.SafeUrl.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_) {\n return safeUrl.privateDoNotAccessOrElseSafeUrlWrappedValue_;\n } else {\n goog.asserts.fail('expected object of type SafeUrl, got \\'' +\n safeUrl + '\\' of type ' + goog.typeOf(safeUrl));\n return 'type_error:SafeUrl';\n }\n};\n\n\n/**\n * Creates a SafeUrl object from a compile-time constant string.\n *\n * Compile-time constant strings are inherently program-controlled and hence\n * trusted.\n *\n * @param {!goog.string.Const} url A compile-time-constant string from which to\n * create a SafeUrl.\n * @return {!goog.html.SafeUrl} A SafeUrl object initialized to `url`.\n */\ngoog.html.SafeUrl.fromConstant = function(url) {\n return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(\n goog.string.Const.unwrap(url));\n};\n\n\n/**\n * A pattern that matches Blob or data types that can have SafeUrls created\n * from URL.createObjectURL(blob) or via a data: URI.\n *\n * This has some parameter support (most notably, we haven't implemented the\n * more complex parts like %-encoded characters or non-alphanumerical ones for\n * simplicity's sake). The specs are fairly complex, and they don't\n * always match Chrome's behavior: we settled on a subset where we're confident\n * all parties involved agree.\n *\n * The spec is available at https://mimesniff.spec.whatwg.org/ (and see\n * https://tools.ietf.org/html/rfc2397 for data: urls, which override some of\n * it).\n * @const\n * @private\n */\ngoog.html.SAFE_MIME_TYPE_PATTERN_ = new RegExp(\n // Note: Due to content-sniffing concerns, only add MIME types for\n // media formats.\n '^(?:audio/(?:3gpp2|3gpp|aac|L16|midi|mp3|mp4|mpeg|oga|ogg|opus|x-m4a|x-wav|wav|webm)|' +\n 'image/(?:bmp|gif|jpeg|jpg|png|tiff|webp|x-icon)|' +\n // TODO(b/68188949): Due to content-sniffing concerns, text/csv should\n // be removed from the whitelist.\n 'text/csv|' +\n 'video/(?:mpeg|mp4|ogg|webm|quicktime))' +\n '(?:;\\\\w+=(?:\\\\w+|\"[\\\\w;=]+\"))*$', // MIME type parameters\n 'i');\n\n\n/**\n * @param {string} mimeType The MIME type to check if safe.\n * @return {boolean} True if the MIME type is safe and creating a Blob via\n * `SafeUrl.fromBlob()` with that type will not fail due to the type. False\n * otherwise.\n */\ngoog.html.SafeUrl.isSafeMimeType = function(mimeType) {\n return goog.html.SAFE_MIME_TYPE_PATTERN_.test(mimeType);\n};\n\n\n/**\n * Creates a SafeUrl wrapping a blob URL for the given `blob`.\n *\n * The blob URL is created with `URL.createObjectURL`. If the MIME type\n * for `blob` is not of a known safe audio, image or video MIME type,\n * then the SafeUrl will wrap {@link #INNOCUOUS_STRING}.\n *\n * @see http://www.w3.org/TR/FileAPI/#url\n * @param {!Blob} blob\n * @return {!goog.html.SafeUrl} The blob URL, or an innocuous string wrapped\n * as a SafeUrl.\n */\ngoog.html.SafeUrl.fromBlob = function(blob) {\n var url = goog.html.SAFE_MIME_TYPE_PATTERN_.test(blob.type) ?\n goog.fs.url.createObjectUrl(blob) :\n goog.html.SafeUrl.INNOCUOUS_STRING;\n return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(url);\n};\n\n\n/**\n * Matches a base-64 data URL, with the first match group being the MIME type.\n * @const\n * @private\n */\ngoog.html.DATA_URL_PATTERN_ = /^data:([^,]*);base64,[a-z0-9+\\/]+=*$/i;\n\n\n/**\n * Creates a SafeUrl wrapping a data: URL, after validating it matches a\n * known-safe audio, image or video MIME type.\n *\n * @param {string} dataUrl A valid base64 data URL with one of the whitelisted\n * audio, image or video MIME types.\n * @return {!goog.html.SafeUrl} A matching safe URL, or {@link INNOCUOUS_STRING}\n * wrapped as a SafeUrl if it does not pass.\n */\ngoog.html.SafeUrl.fromDataUrl = function(dataUrl) {\n // RFC4648 suggest to ignore CRLF in base64 encoding.\n // See https://tools.ietf.org/html/rfc4648.\n // Remove the CR (%0D) and LF (%0A) from the dataUrl.\n var filteredDataUrl = dataUrl.replace(/(%0A|%0D)/g, '');\n // There's a slight risk here that a browser sniffs the content type if it\n // doesn't know the MIME type and executes HTML within the data: URL. For this\n // to cause XSS it would also have to execute the HTML in the same origin\n // of the page with the link. It seems unlikely that both of these will\n // happen, particularly in not really old IEs.\n var match = filteredDataUrl.match(goog.html.DATA_URL_PATTERN_);\n var valid = match && goog.html.SAFE_MIME_TYPE_PATTERN_.test(match[1]);\n return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(\n valid ? filteredDataUrl : goog.html.SafeUrl.INNOCUOUS_STRING);\n};\n\n\n/**\n * Creates a SafeUrl wrapping a tel: URL.\n *\n * @param {string} telUrl A tel URL.\n * @return {!goog.html.SafeUrl} A matching safe URL, or {@link INNOCUOUS_STRING}\n * wrapped as a SafeUrl if it does not pass.\n */\ngoog.html.SafeUrl.fromTelUrl = function(telUrl) {\n // There's a risk that a tel: URL could immediately place a call once\n // clicked, without requiring user confirmation. For that reason it is\n // handled in this separate function.\n if (!goog.string.internal.caseInsensitiveStartsWith(telUrl, 'tel:')) {\n telUrl = goog.html.SafeUrl.INNOCUOUS_STRING;\n }\n return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(\n telUrl);\n};\n\n\n/**\n * Matches a sip/sips URL. We only allow urls that consist of an email address.\n * The characters '?' and '#' are not allowed in the local part of the email\n * address.\n * @const\n * @private\n */\ngoog.html.SIP_URL_PATTERN_ = new RegExp(\n '^sip[s]?:[+a-z0-9_.!$%&\\'*\\\\/=^`{|}~-]+@([a-z0-9-]+\\\\.)+[a-z0-9]{2,63}$',\n 'i');\n\n\n/**\n * Creates a SafeUrl wrapping a sip: URL. We only allow urls that consist of an\n * email address. The characters '?' and '#' are not allowed in the local part\n * of the email address.\n *\n * @param {string} sipUrl A sip URL.\n * @return {!goog.html.SafeUrl} A matching safe URL, or {@link INNOCUOUS_STRING}\n * wrapped as a SafeUrl if it does not pass.\n */\ngoog.html.SafeUrl.fromSipUrl = function(sipUrl) {\n if (!goog.html.SIP_URL_PATTERN_.test(decodeURIComponent(sipUrl))) {\n sipUrl = goog.html.SafeUrl.INNOCUOUS_STRING;\n }\n return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(\n sipUrl);\n};\n\n\n/**\n * Creates a SafeUrl wrapping a fb-messenger://share URL.\n *\n * @param {string} facebookMessengerUrl A facebook messenger URL.\n * @return {!goog.html.SafeUrl} A matching safe URL, or {@link INNOCUOUS_STRING}\n * wrapped as a SafeUrl if it does not pass.\n */\ngoog.html.SafeUrl.fromFacebookMessengerUrl = function(facebookMessengerUrl) {\n if (!goog.string.internal.caseInsensitiveStartsWith(\n facebookMessengerUrl, 'fb-messenger://share')) {\n facebookMessengerUrl = goog.html.SafeUrl.INNOCUOUS_STRING;\n }\n return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(\n facebookMessengerUrl);\n};\n\n/**\n * Creates a SafeUrl wrapping a whatsapp://send URL.\n *\n * @param {string} whatsAppUrl A WhatsApp URL.\n * @return {!goog.html.SafeUrl} A matching safe URL, or {@link INNOCUOUS_STRING}\n * wrapped as a SafeUrl if it does not pass.\n */\ngoog.html.SafeUrl.fromWhatsAppUrl = function(whatsAppUrl) {\n if (!goog.string.internal.caseInsensitiveStartsWith(\n whatsAppUrl, 'whatsapp://send')) {\n whatsAppUrl = goog.html.SafeUrl.INNOCUOUS_STRING;\n }\n return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(\n whatsAppUrl);\n};\n\n/**\n * Creates a SafeUrl wrapping a sms: URL.\n *\n * @param {string} smsUrl A sms URL.\n * @return {!goog.html.SafeUrl} A matching safe URL, or {@link INNOCUOUS_STRING}\n * wrapped as a SafeUrl if it does not pass.\n */\ngoog.html.SafeUrl.fromSmsUrl = function(smsUrl) {\n if (!goog.string.internal.caseInsensitiveStartsWith(smsUrl, 'sms:') ||\n !goog.html.SafeUrl.isSmsUrlBodyValid_(smsUrl)) {\n smsUrl = goog.html.SafeUrl.INNOCUOUS_STRING;\n }\n return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(\n smsUrl);\n};\n\n\n/**\n * Validates SMS URL `body` parameter, which is optional and should appear at\n * most once and should be percent-encoded if present. Rejects many malformed\n * bodies, but may spuriously reject some URLs and does not reject all malformed\n * sms: URLs.\n *\n * @param {string} smsUrl A sms URL.\n * @return {boolean} Whether SMS URL has a valid `body` parameter if it exists.\n * @private\n */\ngoog.html.SafeUrl.isSmsUrlBodyValid_ = function(smsUrl) {\n var hash = smsUrl.indexOf('#');\n if (hash > 0) {\n smsUrl = smsUrl.substring(0, hash);\n }\n var bodyParams = smsUrl.match(/[?&]body=/gi);\n // \"body\" param is optional\n if (!bodyParams) {\n return true;\n }\n // \"body\" MUST only appear once\n if (bodyParams.length > 1) {\n return false;\n }\n // Get the encoded `body` parameter value.\n var bodyValue = smsUrl.match(/[?&]body=([^&]*)/)[1];\n if (!bodyValue) {\n return true;\n }\n try {\n decodeURIComponent(bodyValue);\n } catch (error) {\n return false;\n }\n return /^(?:[a-z0-9\\-_.~]|%[0-9a-f]{2})+$/i.test(bodyValue);\n};\n\n\n/**\n * Creates a SafeUrl wrapping a ssh: URL.\n *\n * @param {string} sshUrl A ssh URL.\n * @return {!goog.html.SafeUrl} A matching safe URL, or {@link INNOCUOUS_STRING}\n * wrapped as a SafeUrl if it does not pass.\n */\ngoog.html.SafeUrl.fromSshUrl = function(sshUrl) {\n if (!goog.string.internal.caseInsensitiveStartsWith(sshUrl, 'ssh://')) {\n sshUrl = goog.html.SafeUrl.INNOCUOUS_STRING;\n }\n return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(\n sshUrl);\n};\n\n/**\n * Sanitizes a Chrome extension URL to SafeUrl, given a compile-time-constant\n * extension identifier. Can also be restricted to chrome extensions.\n *\n * @param {string} url The url to sanitize. Should start with the extension\n * scheme and the extension identifier.\n * @param {!goog.string.Const|!Array<!goog.string.Const>} extensionId The\n * extension id to accept, as a compile-time constant or an array of those.\n *\n * @return {!goog.html.SafeUrl} Either `url` if it's deemed safe, or\n * `INNOCUOUS_STRING` if it's not.\n */\ngoog.html.SafeUrl.sanitizeChromeExtensionUrl = function(url, extensionId) {\n return goog.html.SafeUrl.sanitizeExtensionUrl_(\n /^chrome-extension:\\/\\/([^\\/]+)\\//, url, extensionId);\n};\n\n/**\n * Sanitizes a Firefox extension URL to SafeUrl, given a compile-time-constant\n * extension identifier. Can also be restricted to chrome extensions.\n *\n * @param {string} url The url to sanitize. Should start with the extension\n * scheme and the extension identifier.\n * @param {!goog.string.Const|!Array<!goog.string.Const>} extensionId The\n * extension id to accept, as a compile-time constant or an array of those.\n *\n * @return {!goog.html.SafeUrl} Either `url` if it's deemed safe, or\n * `INNOCUOUS_STRING` if it's not.\n */\ngoog.html.SafeUrl.sanitizeFirefoxExtensionUrl = function(url, extensionId) {\n return goog.html.SafeUrl.sanitizeExtensionUrl_(\n /^moz-extension:\\/\\/([^\\/]+)\\//, url, extensionId);\n};\n\n/**\n * Sanitizes a Edge extension URL to SafeUrl, given a compile-time-constant\n * extension identifier. Can also be restricted to chrome extensions.\n *\n * @param {string} url The url to sanitize. Should start with the extension\n * scheme and the extension identifier.\n * @param {!goog.string.Const|!Array<!goog.string.Const>} extensionId The\n * extension id to accept, as a compile-time constant or an array of those.\n *\n * @return {!goog.html.SafeUrl} Either `url` if it's deemed safe, or\n * `INNOCUOUS_STRING` if it's not.\n */\ngoog.html.SafeUrl.sanitizeEdgeExtensionUrl = function(url, extensionId) {\n return goog.html.SafeUrl.sanitizeExtensionUrl_(\n /^ms-browser-extension:\\/\\/([^\\/]+)\\//, url, extensionId);\n};\n\n/**\n * Private helper for converting extension URLs to SafeUrl, given the scheme for\n * that particular extension type. Use the sanitizeFirefoxExtensionUrl,\n * sanitizeChromeExtensionUrl or sanitizeEdgeExtensionUrl unless you're building\n * new helpers.\n *\n * @private\n * @param {!RegExp} scheme The scheme to accept as a RegExp extracting the\n * extension identifier.\n * @param {string} url The url to sanitize. Should start with the extension\n * scheme and the extension identifier.\n * @param {!goog.string.Const|!Array<!goog.string.Const>} extensionId The\n * extension id to accept, as a compile-time constant or an array of those.\n *\n * @return {!goog.html.SafeUrl} Either `url` if it's deemed safe, or\n * `INNOCUOUS_STRING` if it's not.\n */\ngoog.html.SafeUrl.sanitizeExtensionUrl_ = function(scheme, url, extensionId) {\n var matches = scheme.exec(url);\n if (!matches) {\n url = goog.html.SafeUrl.INNOCUOUS_STRING;\n } else {\n var extractedExtensionId = matches[1];\n var acceptedExtensionIds;\n if (extensionId instanceof goog.string.Const) {\n acceptedExtensionIds = [goog.string.Const.unwrap(extensionId)];\n } else {\n acceptedExtensionIds = extensionId.map(function unwrap(x) {\n return goog.string.Const.unwrap(x);\n });\n }\n if (acceptedExtensionIds.indexOf(extractedExtensionId) == -1) {\n url = goog.html.SafeUrl.INNOCUOUS_STRING;\n }\n }\n return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(url);\n};\n\n\n/**\n * Creates a SafeUrl from TrustedResourceUrl. This is safe because\n * TrustedResourceUrl is more tightly restricted than SafeUrl.\n *\n * @param {!goog.html.TrustedResourceUrl} trustedResourceUrl\n * @return {!goog.html.SafeUrl}\n */\ngoog.html.SafeUrl.fromTrustedResourceUrl = function(trustedResourceUrl) {\n return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(\n goog.html.TrustedResourceUrl.unwrap(trustedResourceUrl));\n};\n\n\n/**\n * A pattern that recognizes a commonly useful subset of URLs that satisfy\n * the SafeUrl contract.\n *\n * This regular expression matches a subset of URLs that will not cause script\n * execution if used in URL context within a HTML document. Specifically, this\n * regular expression matches if (comment from here on and regex copied from\n * Soy's EscapingConventions):\n * (1) Either a protocol in a whitelist (http, https, mailto or ftp).\n * (2) or no protocol. A protocol must be followed by a colon. The below\n * allows that by allowing colons only after one of the characters [/?#].\n * A colon after a hash (#) must be in the fragment.\n * Otherwise, a colon after a (?) must be in a query.\n * Otherwise, a colon after a single solidus (/) must be in a path.\n * Otherwise, a colon after a double solidus (//) must be in the authority\n * (before port).\n *\n * @private\n * @const {!RegExp}\n */\ngoog.html.SAFE_URL_PATTERN_ =\n /^(?:(?:https?|mailto|ftp):|[^:/?#]*(?:[/?#]|$))/i;\n\n/**\n * Public version of goog.html.SAFE_URL_PATTERN_. Updating\n * goog.html.SAFE_URL_PATTERN_ doesn't seem to be backward compatible.\n * Namespace is also changed to goog.html.SafeUrl so it can be imported using\n * goog.require('goog.dom.SafeUrl').\n *\n * TODO(bangert): Remove SAFE_URL_PATTERN_\n * @const {!RegExp}\n */\ngoog.html.SafeUrl.SAFE_URL_PATTERN = goog.html.SAFE_URL_PATTERN_;\n\n\n/**\n * Creates a SafeUrl object from `url`. If `url` is a\n * goog.html.SafeUrl then it is simply returned. Otherwise the input string is\n * validated to match a pattern of commonly used safe URLs.\n *\n * `url` may be a URL with the http, https, mailto or ftp scheme,\n * or a relative URL (i.e., a URL without a scheme; specifically, a\n * scheme-relative, absolute-path-relative, or path-relative URL).\n *\n * @see http://url.spec.whatwg.org/#concept-relative-url\n * @param {string|!goog.string.TypedString} url The URL to validate.\n * @return {!goog.html.SafeUrl} The validated URL, wrapped as a SafeUrl.\n */\ngoog.html.SafeUrl.sanitize = function(url) {\n if (url instanceof goog.html.SafeUrl) {\n return url;\n } else if (typeof url == 'object' && url.implementsGoogStringTypedString) {\n url = /** @type {!goog.string.TypedString} */ (url).getTypedStringValue();\n } else {\n url = String(url);\n }\n if (!goog.html.SAFE_URL_PATTERN_.test(url)) {\n url = goog.html.SafeUrl.INNOCUOUS_STRING;\n }\n return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(url);\n};\n\n/**\n * Creates a SafeUrl object from `url`. If `url` is a\n * goog.html.SafeUrl then it is simply returned. Otherwise the input string is\n * validated to match a pattern of commonly used safe URLs.\n *\n * `url` may be a URL with the http, https, mailto or ftp scheme,\n * or a relative URL (i.e., a URL without a scheme; specifically, a\n * scheme-relative, absolute-path-relative, or path-relative URL).\n *\n * This function asserts (using goog.asserts) that the URL matches this pattern.\n * If it does not, in addition to failing the assert, an innocous URL will be\n * returned.\n *\n * @see http://url.spec.whatwg.org/#concept-relative-url\n * @param {string|!goog.string.TypedString} url The URL to validate.\n * @param {boolean=} opt_allowDataUrl Whether to allow valid data: URLs.\n * @return {!goog.html.SafeUrl} The validated URL, wrapped as a SafeUrl.\n */\ngoog.html.SafeUrl.sanitizeAssertUnchanged = function(url, opt_allowDataUrl) {\n if (url instanceof goog.html.SafeUrl) {\n return url;\n } else if (typeof url == 'object' && url.implementsGoogStringTypedString) {\n url = /** @type {!goog.string.TypedString} */ (url).getTypedStringValue();\n } else {\n url = String(url);\n }\n if (opt_allowDataUrl && /^data:/i.test(url)) {\n var safeUrl = goog.html.SafeUrl.fromDataUrl(url);\n if (safeUrl.getTypedStringValue() == url) {\n return safeUrl;\n }\n }\n if (!goog.asserts.assert(\n goog.html.SAFE_URL_PATTERN_.test(url),\n '%s does not match the safe URL pattern', url)) {\n url = goog.html.SafeUrl.INNOCUOUS_STRING;\n }\n return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(url);\n};\n\n\n\n/**\n * Type marker for the SafeUrl type, used to implement additional run-time\n * type checking.\n * @const {!Object}\n * @private\n */\ngoog.html.SafeUrl.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ = {};\n\n\n/**\n * Package-internal utility method to create SafeUrl instances.\n *\n * @param {string} url The string to initialize the SafeUrl object with.\n * @return {!goog.html.SafeUrl} The initialized SafeUrl object.\n * @package\n */\ngoog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse = function(\n url) {\n return new goog.html.SafeUrl(\n goog.html.SafeUrl.CONSTRUCTOR_TOKEN_PRIVATE_, url);\n};\n\n\n/**\n * A SafeUrl corresponding to the special about:blank url.\n * @const {!goog.html.SafeUrl}\n */\ngoog.html.SafeUrl.ABOUT_BLANK =\n goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(\n 'about:blank');\n\n/**\n * Token used to ensure that object is created only from this file. No code\n * outside of this file can access this token.\n * @private {!Object}\n * @const\n */\ngoog.html.SafeUrl.CONSTRUCTOR_TOKEN_PRIVATE_ = {};\n","~:compiled-at",1584073468416,"~:source-map-json","{\n\"version\":3,\n\"file\":\"goog.html.safeurl.js\",\n\"lineCount\":288,\n\"mappings\":\"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\",\n\"sources\":[\"goog/html/safeurl.js\"],\n\"sourcesContent\":[\"// Copyright 2013 The Closure Library Authors. All Rights Reserved.\\n//\\n// Licensed under the Apache License, Version 2.0 (the \\\"License\\\");\\n// you may not use this file except in compliance with the License.\\n// You may obtain a copy of the License at\\n//\\n// http://www.apache.org/licenses/LICENSE-2.0\\n//\\n// Unless required by applicable law or agreed to in writing, software\\n// distributed under the License is distributed on an \\\"AS-IS\\\" BASIS,\\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\\n// See the License for the specific language governing permissions and\\n// limitations under the License.\\n\\n/**\\n * @fileoverview The SafeUrl type and its builders.\\n *\\n * TODO(xtof): Link to document stating type contract.\\n */\\n\\ngoog.provide('goog.html.SafeUrl');\\n\\ngoog.require('goog.asserts');\\ngoog.require('goog.fs.url');\\ngoog.require('goog.html.TrustedResourceUrl');\\ngoog.require('goog.i18n.bidi.Dir');\\ngoog.require('goog.i18n.bidi.DirectionalString');\\ngoog.require('goog.string.Const');\\ngoog.require('goog.string.TypedString');\\ngoog.require('goog.string.internal');\\n\\n\\n\\n/**\\n * A string that is safe to use in URL context in DOM APIs and HTML documents.\\n *\\n * A SafeUrl is a string-like object that carries the security type contract\\n * that its value as a string will not cause untrusted script execution\\n * when evaluated as a hyperlink URL in a browser.\\n *\\n * Values of this type are guaranteed to be safe to use in URL/hyperlink\\n * contexts, such as assignment to URL-valued DOM properties, in the sense that\\n * the use will not result in a Cross-Site-Scripting vulnerability. Similarly,\\n * SafeUrls can be interpolated into the URL context of an HTML template (e.g.,\\n * inside a href attribute). However, appropriate HTML-escaping must still be\\n * applied.\\n *\\n * Note that, as documented in `goog.html.SafeUrl.unwrap`, this type's\\n * contract does not guarantee that instances are safe to interpolate into HTML\\n * without appropriate escaping.\\n *\\n * Note also that this type's contract does not imply any guarantees regarding\\n * the resource the URL refers to. In particular, SafeUrls are <b>not</b>\\n * safe to use in a context where the referred-to resource is interpreted as\\n * trusted code, e.g., as the src of a script tag.\\n *\\n * Instances of this typ