229 lines
9.6 KiB
JavaScript
229 lines
9.6 KiB
JavaScript
|
/*TRANSPILED*//*
|
||
|
|
||
|
Copyright The Closure Library Authors.
|
||
|
SPDX-License-Identifier: Apache-2.0
|
||
|
*/
|
||
|
'use strict';
|
||
|
goog.provide("goog.html.SafeUrl");
|
||
|
goog.require("goog.asserts");
|
||
|
goog.require("goog.fs.url");
|
||
|
goog.require("goog.html.TrustedResourceUrl");
|
||
|
goog.require("goog.string.Const");
|
||
|
goog.require("goog.string.TypedString");
|
||
|
goog.require("goog.string.internal");
|
||
|
goog.html.SafeUrl = class {
|
||
|
constructor(value, token) {
|
||
|
this.privateDoNotAccessOrElseSafeUrlWrappedValue_ = token === goog.html.SafeUrl.CONSTRUCTOR_TOKEN_PRIVATE_ ? value : "";
|
||
|
}
|
||
|
toString() {
|
||
|
return this.privateDoNotAccessOrElseSafeUrlWrappedValue_.toString();
|
||
|
}
|
||
|
};
|
||
|
goog.html.SafeUrl.INNOCUOUS_STRING = "about:invalid#zClosurez";
|
||
|
goog.html.SafeUrl.prototype.implementsGoogStringTypedString = true;
|
||
|
goog.html.SafeUrl.prototype.getTypedStringValue = function() {
|
||
|
return this.privateDoNotAccessOrElseSafeUrlWrappedValue_.toString();
|
||
|
};
|
||
|
goog.html.SafeUrl.unwrap = function(safeUrl) {
|
||
|
if (safeUrl instanceof goog.html.SafeUrl && safeUrl.constructor === goog.html.SafeUrl) {
|
||
|
return safeUrl.privateDoNotAccessOrElseSafeUrlWrappedValue_;
|
||
|
} else {
|
||
|
goog.asserts.fail("expected object of type SafeUrl, got '" + safeUrl + "' of type " + goog.typeOf(safeUrl));
|
||
|
return "type_error:SafeUrl";
|
||
|
}
|
||
|
};
|
||
|
goog.html.SafeUrl.fromConstant = function(url) {
|
||
|
return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(goog.string.Const.unwrap(url));
|
||
|
};
|
||
|
goog.html.SAFE_MIME_TYPE_PATTERN_ = new RegExp("^(?:audio/(?:3gpp2|3gpp|aac|L16|midi|mp3|mp4|mpeg|oga|ogg|opus|x-m4a|x-matroska|x-wav|wav|webm)|" + "font/\\w+|" + "image/(?:bmp|gif|jpeg|jpg|png|tiff|webp|x-icon|heic|heif)|" + "video/(?:mpeg|mp4|ogg|webm|quicktime|x-matroska))" + '(?:;\\w+\x3d(?:\\w+|"[\\w;,\x3d ]+"))*$', "i");
|
||
|
goog.html.SafeUrl.isSafeMimeType = function(mimeType) {
|
||
|
return goog.html.SAFE_MIME_TYPE_PATTERN_.test(mimeType);
|
||
|
};
|
||
|
goog.html.SafeUrl.fromBlob = function(blob) {
|
||
|
var url = goog.html.SafeUrl.isSafeMimeType(blob.type) ? goog.fs.url.createObjectUrl(blob) : goog.html.SafeUrl.INNOCUOUS_STRING;
|
||
|
return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(url);
|
||
|
};
|
||
|
goog.html.SafeUrl.revokeObjectUrl = function(safeUrl) {
|
||
|
var url = safeUrl.getTypedStringValue();
|
||
|
if (url !== goog.html.SafeUrl.INNOCUOUS_STRING) {
|
||
|
goog.fs.url.revokeObjectUrl(url);
|
||
|
}
|
||
|
};
|
||
|
goog.html.SafeUrl.fromMediaSource = function(mediaSource) {
|
||
|
goog.asserts.assert("MediaSource" in goog.global, "No support for MediaSource");
|
||
|
const url = mediaSource instanceof MediaSource ? goog.fs.url.createObjectUrl(mediaSource) : goog.html.SafeUrl.INNOCUOUS_STRING;
|
||
|
return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(url);
|
||
|
};
|
||
|
goog.html.DATA_URL_PATTERN_ = /^data:(.*);base64,[a-z0-9+\/]+=*$/i;
|
||
|
goog.html.SafeUrl.tryFromDataUrl = function(dataUrl) {
|
||
|
dataUrl = String(dataUrl);
|
||
|
var filteredDataUrl = dataUrl.replace(/(%0A|%0D)/g, "");
|
||
|
var match = filteredDataUrl.match(goog.html.DATA_URL_PATTERN_);
|
||
|
if (match) {
|
||
|
return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(filteredDataUrl);
|
||
|
}
|
||
|
return null;
|
||
|
};
|
||
|
goog.html.SafeUrl.fromDataUrl = function(dataUrl) {
|
||
|
return goog.html.SafeUrl.tryFromDataUrl(dataUrl) || goog.html.SafeUrl.INNOCUOUS_URL;
|
||
|
};
|
||
|
goog.html.SafeUrl.fromTelUrl = function(telUrl) {
|
||
|
if (!goog.string.internal.caseInsensitiveStartsWith(telUrl, "tel:")) {
|
||
|
telUrl = goog.html.SafeUrl.INNOCUOUS_STRING;
|
||
|
}
|
||
|
return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(telUrl);
|
||
|
};
|
||
|
goog.html.SIP_URL_PATTERN_ = new RegExp("^sip[s]?:[+a-z0-9_.!$%\x26'*\\/\x3d^`{|}~-]+@([a-z0-9-]+\\.)+[a-z0-9]{2,63}$", "i");
|
||
|
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);
|
||
|
};
|
||
|
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);
|
||
|
};
|
||
|
goog.html.SafeUrl.fromWhatsAppUrl = function(whatsAppUrl) {
|
||
|
if (!goog.string.internal.caseInsensitiveStartsWith(whatsAppUrl, "whatsapp://send")) {
|
||
|
whatsAppUrl = goog.html.SafeUrl.INNOCUOUS_STRING;
|
||
|
}
|
||
|
return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(whatsAppUrl);
|
||
|
};
|
||
|
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);
|
||
|
};
|
||
|
goog.html.SafeUrl.isSmsUrlBodyValid_ = function(smsUrl) {
|
||
|
var hash = smsUrl.indexOf("#");
|
||
|
if (hash > 0) {
|
||
|
smsUrl = smsUrl.substring(0, hash);
|
||
|
}
|
||
|
var bodyParams = smsUrl.match(/[?&]body=/gi);
|
||
|
if (!bodyParams) {
|
||
|
return true;
|
||
|
}
|
||
|
if (bodyParams.length > 1) {
|
||
|
return false;
|
||
|
}
|
||
|
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);
|
||
|
};
|
||
|
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);
|
||
|
};
|
||
|
goog.html.SafeUrl.sanitizeChromeExtensionUrl = function(url, extensionId) {
|
||
|
return goog.html.SafeUrl.sanitizeExtensionUrl_(/^chrome-extension:\/\/([^\/]+)\//, url, extensionId);
|
||
|
};
|
||
|
goog.html.SafeUrl.sanitizeFirefoxExtensionUrl = function(url, extensionId) {
|
||
|
return goog.html.SafeUrl.sanitizeExtensionUrl_(/^moz-extension:\/\/([^\/]+)\//, url, extensionId);
|
||
|
};
|
||
|
goog.html.SafeUrl.sanitizeEdgeExtensionUrl = function(url, extensionId) {
|
||
|
return goog.html.SafeUrl.sanitizeExtensionUrl_(/^ms-browser-extension:\/\/([^\/]+)\//, url, extensionId);
|
||
|
};
|
||
|
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);
|
||
|
};
|
||
|
goog.html.SafeUrl.fromTrustedResourceUrl = function(trustedResourceUrl) {
|
||
|
return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(goog.html.TrustedResourceUrl.unwrap(trustedResourceUrl));
|
||
|
};
|
||
|
goog.html.SAFE_URL_PATTERN_ = /^(?:(?:https?|mailto|ftp):|[^:/?#]*(?:[/?#]|$))/i;
|
||
|
goog.html.SafeUrl.SAFE_URL_PATTERN = goog.html.SAFE_URL_PATTERN_;
|
||
|
goog.html.SafeUrl.trySanitize = function(url) {
|
||
|
if (url instanceof goog.html.SafeUrl) {
|
||
|
return url;
|
||
|
}
|
||
|
if (typeof url == "object" && url.implementsGoogStringTypedString) {
|
||
|
url = url.getTypedStringValue();
|
||
|
} else {
|
||
|
url = String(url);
|
||
|
}
|
||
|
if (!goog.html.SAFE_URL_PATTERN_.test(url)) {
|
||
|
return goog.html.SafeUrl.tryFromDataUrl(url);
|
||
|
}
|
||
|
return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(url);
|
||
|
};
|
||
|
goog.html.SafeUrl.sanitize = function(url) {
|
||
|
return goog.html.SafeUrl.trySanitize(url) || goog.html.SafeUrl.INNOCUOUS_URL;
|
||
|
};
|
||
|
goog.html.SafeUrl.sanitizeAssertUnchanged = function(url, opt_allowDataUrl) {
|
||
|
if (url instanceof goog.html.SafeUrl) {
|
||
|
return url;
|
||
|
} else if (typeof url == "object" && url.implementsGoogStringTypedString) {
|
||
|
url = 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);
|
||
|
};
|
||
|
goog.html.SafeUrl.extractScheme = function(url) {
|
||
|
let parsedUrl;
|
||
|
try {
|
||
|
parsedUrl = new URL(url);
|
||
|
} catch (e) {
|
||
|
return "https:";
|
||
|
}
|
||
|
return parsedUrl.protocol;
|
||
|
};
|
||
|
goog.html.SafeUrl.sanitizeJavascriptUrlAssertUnchanged = function(url) {
|
||
|
if (url instanceof goog.html.SafeUrl) {
|
||
|
return url;
|
||
|
} else if (typeof url == "object" && url.implementsGoogStringTypedString) {
|
||
|
url = url.getTypedStringValue();
|
||
|
} else {
|
||
|
url = String(url);
|
||
|
}
|
||
|
const parsedScheme = goog.html.SafeUrl.extractScheme(url);
|
||
|
if (!goog.asserts.assert(parsedScheme !== "javascript:", "%s is a javascript: URL", url)) {
|
||
|
url = goog.html.SafeUrl.INNOCUOUS_STRING;
|
||
|
}
|
||
|
return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(url);
|
||
|
};
|
||
|
goog.html.SafeUrl.CONSTRUCTOR_TOKEN_PRIVATE_ = {};
|
||
|
goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse = function(url) {
|
||
|
return new goog.html.SafeUrl(url, goog.html.SafeUrl.CONSTRUCTOR_TOKEN_PRIVATE_);
|
||
|
};
|
||
|
goog.html.SafeUrl.INNOCUOUS_URL = goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(goog.html.SafeUrl.INNOCUOUS_STRING);
|
||
|
goog.html.SafeUrl.ABOUT_BLANK = goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse("about:blank");
|