UNPKG

closure-builder

Version:

Simple Closure, Soy and JavaScript Build system

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