Bug 1290668 - unbreak view-source links between http and https pages, r=smaug
MozReview-Commit-ID: B4nXTkMC5LE
This commit is contained in:
@@ -653,37 +653,6 @@ EqualOrSubdomain(nsIURI* aProbeArg, nsIURI* aBase)
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
AllSchemesMatch(nsIURI* aURI, nsIURI* aOtherURI)
|
||||
{
|
||||
auto stringComparator = nsCaseInsensitiveCStringComparator();
|
||||
nsCOMPtr<nsIURI> currentURI = aURI;
|
||||
nsCOMPtr<nsIURI> currentOtherURI = aOtherURI;
|
||||
while (currentURI && currentOtherURI) {
|
||||
nsAutoCString scheme, otherScheme;
|
||||
currentURI->GetScheme(scheme);
|
||||
currentOtherURI->GetScheme(otherScheme);
|
||||
if (!scheme.Equals(otherScheme, stringComparator)) {
|
||||
return false;
|
||||
}
|
||||
nsCOMPtr<nsINestedURI> nestedURI = do_QueryInterface(currentURI);
|
||||
nsCOMPtr<nsINestedURI> nestedOtherURI = do_QueryInterface(currentOtherURI);
|
||||
// If neither are nested and all schemes have matched so far
|
||||
// (or we would have bailed already), we're the same:
|
||||
if (!nestedURI && !nestedOtherURI) {
|
||||
return true;
|
||||
}
|
||||
// If one is nested and the other not, they're not equal:
|
||||
if (!nestedURI != !nestedOtherURI) {
|
||||
return false;
|
||||
}
|
||||
// At this stage, both are still nested URIs, so let's play again:
|
||||
nestedURI->GetInnerURI(getter_AddRefs(currentURI));
|
||||
nestedOtherURI->GetInnerURI(getter_AddRefs(currentOtherURI));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScriptSecurityManager::CheckLoadURIWithPrincipal(nsIPrincipal* aPrincipal,
|
||||
nsIURI *aTargetURI,
|
||||
@@ -806,53 +775,50 @@ nsScriptSecurityManager::CheckLoadURIWithPrincipal(nsIPrincipal* aPrincipal,
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
else if (AllSchemesMatch(sourceURI, aTargetURI) ||
|
||||
(sViewSourceReachableFromInner &&
|
||||
sourceScheme.EqualsIgnoreCase(targetScheme.get()) &&
|
||||
NS_SUCCEEDED(aTargetURI->SchemeIs("view-source", &targetIsViewSource)) &&
|
||||
targetIsViewSource))
|
||||
else if (sViewSourceReachableFromInner &&
|
||||
sourceScheme.EqualsIgnoreCase(targetScheme.get()) &&
|
||||
NS_SUCCEEDED(aTargetURI->SchemeIs("view-source", &targetIsViewSource)) &&
|
||||
targetIsViewSource)
|
||||
{
|
||||
// every scheme can access another URI from the same scheme,
|
||||
// as long as they don't represent null principals...
|
||||
// Or they don't require an special permission to do so
|
||||
// See bug#773886
|
||||
rv = NS_URIChainHasFlags(targetBaseURI,
|
||||
nsIProtocolHandler::URI_CROSS_ORIGIN_NEEDS_WEBAPPS_PERM,
|
||||
&hasFlags);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (hasFlags) {
|
||||
// Let apps load the whitelisted theme resources even if they don't
|
||||
// have the webapps-manage permission but have the themeable one.
|
||||
// Resources from the theme origin are also allowed to load from
|
||||
// the theme origin (eg. stylesheets using images from the theme).
|
||||
auto themeOrigin = Preferences::GetCString("b2g.theme.origin");
|
||||
if (themeOrigin) {
|
||||
nsAutoCString targetOrigin;
|
||||
nsPrincipal::GetOriginForURI(targetBaseURI, targetOrigin);
|
||||
if (targetOrigin.Equals(themeOrigin)) {
|
||||
nsAutoCString pOrigin;
|
||||
aPrincipal->GetOrigin(pOrigin);
|
||||
return nsContentUtils::IsExactSitePermAllow(aPrincipal, "themeable") ||
|
||||
pOrigin.Equals(themeOrigin)
|
||||
? NS_OK : NS_ERROR_DOM_BAD_URI;
|
||||
}
|
||||
}
|
||||
// In this case, we allow opening only if the source and target URIS
|
||||
// are on the same domain, or the opening URI has the webapps
|
||||
// permision granted
|
||||
if (!SecurityCompareURIs(sourceBaseURI, targetBaseURI) &&
|
||||
!nsContentUtils::IsExactSitePermAllow(aPrincipal, WEBAPPS_PERM_NAME)) {
|
||||
return NS_ERROR_DOM_BAD_URI;
|
||||
}
|
||||
}
|
||||
// exception for foo: linking to view-source:foo for reftests...
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// If the schemes don't match, the policy is specified by the protocol
|
||||
// flags on the target URI.
|
||||
return CheckLoadURIFlags(sourceURI, aTargetURI, sourceBaseURI,
|
||||
targetBaseURI, aFlags);
|
||||
// If we get here, check all the schemes can link to each other, from the top down:
|
||||
nsCaseInsensitiveCStringComparator stringComparator;
|
||||
nsCOMPtr<nsIURI> currentURI = sourceURI;
|
||||
nsCOMPtr<nsIURI> currentOtherURI = aTargetURI;
|
||||
while (currentURI && currentOtherURI) {
|
||||
nsAutoCString scheme, otherScheme;
|
||||
currentURI->GetScheme(scheme);
|
||||
currentOtherURI->GetScheme(otherScheme);
|
||||
|
||||
// If schemes are not equal, check if the URI flags of the current
|
||||
// target URI allow the current source URI to link to it.
|
||||
// The policy is specified by the protocol flags on both URIs.
|
||||
if (!scheme.Equals(otherScheme, stringComparator)) {
|
||||
return CheckLoadURIFlags(currentURI, currentOtherURI,
|
||||
sourceBaseURI, targetBaseURI, aFlags);
|
||||
}
|
||||
// Otherwise... check if we can nest another level:
|
||||
nsCOMPtr<nsINestedURI> nestedURI = do_QueryInterface(currentURI);
|
||||
nsCOMPtr<nsINestedURI> nestedOtherURI = do_QueryInterface(currentOtherURI);
|
||||
|
||||
// If schemes match and neither URI is nested further, we're OK.
|
||||
if (!nestedURI && !nestedOtherURI) {
|
||||
return NS_OK;
|
||||
}
|
||||
// If one is nested and the other isn't, something is wrong.
|
||||
if (!nestedURI != !nestedOtherURI) {
|
||||
return NS_ERROR_DOM_BAD_URI;
|
||||
}
|
||||
// Otherwise, both should be nested and we'll go through the loop again.
|
||||
nestedURI->GetInnerURI(getter_AddRefs(currentURI));
|
||||
nestedOtherURI->GetInnerURI(getter_AddRefs(currentOtherURI));
|
||||
}
|
||||
|
||||
// We should never get here. We should always return from inside the loop.
|
||||
return NS_ERROR_DOM_BAD_URI;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user