зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1491728 - Fix ContentPrincipal::GetSiteOrigin to handle IPv6 addresses correctly. r=bzbarsky
The problem is that we used ThirdPartyUtil.getBaseDomain and for IP addresses that returns the host, and for IPv6 addresses GetHost strips the '[' and ']' brackets. Then when we passed that IP address to SetHost, we failed because SetHost wants the brackets to be present. This patch changes GetSiteOrigin to call getBaseDomain on the TLD service instead, so we can handle this case ourselves by not calling SetHost when we have an IP address. GetBaseDomain still uses ThirdPartyUtil. I tried to add a test for this (with an iframe + postMessage) but the mochitest http server doesn't support IPv6. Differential Revision: https://phabricator.services.mozilla.com/D6523 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
3bb99d50d2
Коммит
cfc1f8fa90
|
@ -391,17 +391,18 @@ ContentPrincipal::SetDomain(nsIURI* aDomain)
|
|||
}
|
||||
|
||||
static nsresult
|
||||
GetBaseDomainHelper(const nsCOMPtr<nsIURI>& aCodebase,
|
||||
bool* aHasBaseDomain,
|
||||
nsACString& aBaseDomain)
|
||||
GetSpecialBaseDomain(const nsCOMPtr<nsIURI>& aCodebase,
|
||||
bool* aHandled,
|
||||
nsACString& aBaseDomain)
|
||||
{
|
||||
*aHasBaseDomain = false;
|
||||
*aHandled = false;
|
||||
|
||||
// For a file URI, we return the file path.
|
||||
if (NS_URIIsLocalFile(aCodebase)) {
|
||||
nsCOMPtr<nsIURL> url = do_QueryInterface(aCodebase);
|
||||
|
||||
if (url) {
|
||||
*aHandled = true;
|
||||
return url->GetFilePath(aBaseDomain);
|
||||
}
|
||||
}
|
||||
|
@ -415,52 +416,84 @@ GetBaseDomainHelper(const nsCOMPtr<nsIURI>& aCodebase,
|
|||
}
|
||||
|
||||
if (hasNoRelativeFlag) {
|
||||
*aHandled = true;
|
||||
return aCodebase->GetSpec(aBaseDomain);
|
||||
}
|
||||
|
||||
*aHasBaseDomain = true;
|
||||
|
||||
// For everything else, we ask the TLD service via
|
||||
// the ThirdPartyUtil.
|
||||
nsCOMPtr<mozIThirdPartyUtil> thirdPartyUtil =
|
||||
do_GetService(THIRDPARTYUTIL_CONTRACTID);
|
||||
if (thirdPartyUtil) {
|
||||
return thirdPartyUtil->GetBaseDomain(aCodebase, aBaseDomain);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ContentPrincipal::GetBaseDomain(nsACString& aBaseDomain)
|
||||
{
|
||||
bool hasBaseDomain;
|
||||
return GetBaseDomainHelper(mCodebase, &hasBaseDomain, aBaseDomain);
|
||||
// Handle some special URIs first.
|
||||
bool handled;
|
||||
nsresult rv = GetSpecialBaseDomain(mCodebase, &handled, aBaseDomain);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (handled) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// For everything else, we ask the TLD service via the ThirdPartyUtil.
|
||||
nsCOMPtr<mozIThirdPartyUtil> thirdPartyUtil =
|
||||
do_GetService(THIRDPARTYUTIL_CONTRACTID);
|
||||
if (!thirdPartyUtil) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
return thirdPartyUtil->GetBaseDomain(mCodebase, aBaseDomain);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ContentPrincipal::GetSiteOrigin(nsACString& aSiteOrigin)
|
||||
{
|
||||
// Determine our base domain.
|
||||
bool hasBaseDomain;
|
||||
// Handle some special URIs first.
|
||||
nsAutoCString baseDomain;
|
||||
nsresult rv = GetBaseDomainHelper(mCodebase, &hasBaseDomain, baseDomain);
|
||||
bool handled;
|
||||
nsresult rv = GetSpecialBaseDomain(mCodebase, &handled, baseDomain);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!hasBaseDomain) {
|
||||
if (handled) {
|
||||
// This is a special URI ("file:", "about:", "view-source:", etc). Just
|
||||
// return the origin.
|
||||
return GetOrigin(aSiteOrigin);
|
||||
}
|
||||
|
||||
// For everything else, we ask the TLD service. Note that, unlike in
|
||||
// GetBaseDomain, we don't use ThirdPartyUtil.getBaseDomain because if the
|
||||
// host is an IP address that returns the raw address and we can't use it with
|
||||
// SetHost below because SetHost expects '[' and ']' around IPv6 addresses.
|
||||
// See bug 1491728.
|
||||
nsCOMPtr<nsIEffectiveTLDService> tldService =
|
||||
do_GetService(NS_EFFECTIVETLDSERVICE_CONTRACTID);
|
||||
if (!tldService) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
bool gotBaseDomain = false;
|
||||
rv = tldService->GetBaseDomain(mCodebase, 0, baseDomain);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
gotBaseDomain = true;
|
||||
} else {
|
||||
// If this is an IP address or something like "localhost", we just continue
|
||||
// with gotBaseDomain = false.
|
||||
if (rv != NS_ERROR_HOST_IS_IP_ADDRESS &&
|
||||
rv != NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: Calling `SetHostPort` with a portless domain is insufficient to clear
|
||||
// the port, so an extra `SetPort` call has to be made.
|
||||
nsCOMPtr<nsIURI> siteUri;
|
||||
rv = NS_MutateURI(mCodebase)
|
||||
.SetUserPass(EmptyCString())
|
||||
.SetPort(-1)
|
||||
.SetHostPort(baseDomain)
|
||||
.Finalize(siteUri);
|
||||
NS_MutateURI mutator(mCodebase);
|
||||
mutator.SetUserPass(EmptyCString())
|
||||
.SetPort(-1);
|
||||
if (gotBaseDomain) {
|
||||
mutator.SetHost(baseDomain);
|
||||
}
|
||||
rv = mutator.Finalize(siteUri);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv), "failed to create siteUri");
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче