зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1195172 - Use channel->ascynOpen2 layout/style/FontFaceSet.cpp (r=bz,cam)
This commit is contained in:
Родитель
b46dc013d9
Коммит
9ab1648f67
|
@ -229,7 +229,8 @@ DoContentSecurityChecks(nsIURI* aURI, nsILoadInfo* aLoadInfo)
|
|||
}
|
||||
|
||||
case nsIContentPolicy::TYPE_FONT: {
|
||||
MOZ_ASSERT(false, "contentPolicyType not supported yet");
|
||||
mimeTypeGuess = EmptyCString();
|
||||
requestingContext = aLoadInfo->LoadingNode();
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include "gfxUserFontSet.h"
|
||||
#include "gfxPlatform.h"
|
||||
#include "nsContentPolicyUtils.h"
|
||||
#include "nsUnicharUtils.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsIJARChannel.h"
|
||||
|
@ -1203,6 +1204,13 @@ gfxUserFontSet::UserFontCache::GetFont(nsIURI* aSrcURI,
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
// We have to perform another content policy check here to prevent
|
||||
// cache poisoning. E.g. a.com loads a font into the cache but
|
||||
// b.com has a CSP not allowing any fonts to be loaded.
|
||||
if (!aUserFontEntry->mFontSet->IsFontLoadAllowed(aSrcURI, aPrincipal)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Ignore principal when looking up a data: URI.
|
||||
nsIPrincipal* principal;
|
||||
if (IgnorePrincipal(aSrcURI)) {
|
||||
|
@ -1217,12 +1225,14 @@ gfxUserFontSet::UserFontCache::GetFont(nsIURI* aSrcURI,
|
|||
return entry->GetFontEntry();
|
||||
}
|
||||
|
||||
// The channel is never openend; to be conservative we use the most
|
||||
// restrictive security flag: SEC_REQUIRE_SAME_ORIGIN_DATA_INHERITS.
|
||||
nsCOMPtr<nsIChannel> chan;
|
||||
if (NS_FAILED(NS_NewChannel(getter_AddRefs(chan),
|
||||
aSrcURI,
|
||||
aPrincipal,
|
||||
nsILoadInfo::SEC_NORMAL,
|
||||
nsIContentPolicy::TYPE_OTHER))) {
|
||||
nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_INHERITS,
|
||||
nsIContentPolicy::TYPE_FONT))) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
|
|
@ -262,6 +262,10 @@ public:
|
|||
nsIPrincipal** aPrincipal,
|
||||
bool* aBypassCache) = 0;
|
||||
|
||||
// check whether content policies allow the given URI to load.
|
||||
virtual bool IsFontLoadAllowed(nsIURI* aFontLocation,
|
||||
nsIPrincipal* aPrincipal) = 0;
|
||||
|
||||
// initialize the process that loads external font data, which upon
|
||||
// completion will call FontDataDownloadComplete method
|
||||
virtual nsresult StartLoad(gfxUserFontEntry* aUserFontEntry,
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "mozilla/Snprintf.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
#include "nsCORSListenerProxy.h"
|
||||
#include "nsContentPolicyUtils.h"
|
||||
#include "nsCSSParser.h"
|
||||
#include "nsDeviceContext.h"
|
||||
#include "nsFontFaceLoader.h"
|
||||
|
@ -597,10 +598,9 @@ FontFaceSet::StartLoad(gfxUserFontEntry* aUserFontEntry,
|
|||
aFontFaceSrc->mURI,
|
||||
mDocument,
|
||||
aUserFontEntry->GetPrincipal(),
|
||||
nsILoadInfo::SEC_NORMAL,
|
||||
nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS,
|
||||
nsIContentPolicy::TYPE_FONT,
|
||||
loadGroup);
|
||||
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
RefPtr<nsFontFaceLoader> fontLoader =
|
||||
|
@ -646,25 +646,9 @@ FontFaceSet::StartLoad(gfxUserFontEntry* aUserFontEntry,
|
|||
nsINetworkPredictor::LEARN_LOAD_SUBRESOURCE,
|
||||
loadGroup);
|
||||
|
||||
bool inherits = false;
|
||||
rv = NS_URIChainHasFlags(aFontFaceSrc->mURI,
|
||||
nsIProtocolHandler::URI_INHERITS_SECURITY_CONTEXT,
|
||||
&inherits);
|
||||
if (NS_SUCCEEDED(rv) && inherits) {
|
||||
// allow data, javascript, etc URI's
|
||||
rv = channel->AsyncOpen(streamLoader, nullptr);
|
||||
} else {
|
||||
RefPtr<nsCORSListenerProxy> listener =
|
||||
new nsCORSListenerProxy(streamLoader, aUserFontEntry->GetPrincipal(), false);
|
||||
// Doesn't matter what data: URI handling we use here, since we
|
||||
// don't even use a CORS listener proxy for the data: case.
|
||||
rv = listener->Init(channel, DataURIHandling::Disallow);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = channel->AsyncOpen(listener, nullptr);
|
||||
}
|
||||
if (NS_FAILED(rv)) {
|
||||
fontLoader->DropChannel(); // explicitly need to break ref cycle
|
||||
}
|
||||
rv = channel->AsyncOpen2(streamLoader);
|
||||
if (NS_FAILED(rv)) {
|
||||
fontLoader->DropChannel(); // explicitly need to break ref cycle
|
||||
}
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
|
@ -1338,13 +1322,6 @@ FontFaceSet::CheckFontLoad(const gfxFontFaceSrc* aFontFaceSrc,
|
|||
*aPrincipal = aFontFaceSrc->mOriginPrincipal;
|
||||
}
|
||||
|
||||
nsresult rv = nsFontFaceLoader::CheckLoadAllowed(*aPrincipal,
|
||||
aFontFaceSrc->mURI,
|
||||
mDocument);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
*aBypassCache = false;
|
||||
|
||||
nsCOMPtr<nsIDocShell> docShell = mDocument->GetDocShell();
|
||||
|
@ -1363,7 +1340,28 @@ FontFaceSet::CheckFontLoad(const gfxFontFaceSrc* aFontFaceSrc,
|
|||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
// @arg aPrincipal: generally this is mDocument->NodePrincipal() but
|
||||
// might also be the original principal which enables user stylesheets
|
||||
// to load font files via @font-face rules.
|
||||
bool
|
||||
FontFaceSet::IsFontLoadAllowed(nsIURI* aFontLocation, nsIPrincipal* aPrincipal)
|
||||
{
|
||||
int16_t shouldLoad = nsIContentPolicy::ACCEPT;
|
||||
nsresult rv = NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_FONT,
|
||||
aFontLocation,
|
||||
aPrincipal,
|
||||
mDocument,
|
||||
EmptyCString(), // mime type
|
||||
nullptr, // aExtra
|
||||
&shouldLoad,
|
||||
nsContentUtils::GetContentPolicy(),
|
||||
nsContentUtils::GetSecurityManager());
|
||||
|
||||
return NS_SUCCEEDED(rv) && NS_CP_ACCEPTED(shouldLoad);
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -1379,18 +1377,21 @@ FontFaceSet::SyncLoadFontData(gfxUserFontEntry* aFontToLoad,
|
|||
// node and a principal. This is because the document where the font is
|
||||
// being loaded might have a different origin from the principal of the
|
||||
// stylesheet that initiated the font load.
|
||||
// Further, we only get here for data: loads, so it doesn't really matter
|
||||
// whether we use SEC_ALLOW_CROSS_ORIGIN_DATA_INHERITS or not, to be more
|
||||
// restrictive we use SEC_REQUIRE_SAME_ORIGIN_DATA_INHERITS.
|
||||
rv = NS_NewChannelWithTriggeringPrincipal(getter_AddRefs(channel),
|
||||
aFontFaceSrc->mURI,
|
||||
mDocument,
|
||||
aFontToLoad->GetPrincipal(),
|
||||
nsILoadInfo::SEC_NORMAL,
|
||||
nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_INHERITS,
|
||||
nsIContentPolicy::TYPE_FONT);
|
||||
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// blocking stream is OK for data URIs
|
||||
nsCOMPtr<nsIInputStream> stream;
|
||||
rv = channel->Open(getter_AddRefs(stream));
|
||||
rv = channel->Open2(getter_AddRefs(stream));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
uint64_t bufferLength64;
|
||||
|
@ -1742,6 +1743,14 @@ FontFaceSet::UserFontSet::CheckFontLoad(const gfxFontFaceSrc* aFontFaceSrc,
|
|||
return mFontFaceSet->CheckFontLoad(aFontFaceSrc, aPrincipal, aBypassCache);
|
||||
}
|
||||
|
||||
/* virtual */ bool
|
||||
FontFaceSet::UserFontSet::IsFontLoadAllowed(nsIURI* aFontLocation,
|
||||
nsIPrincipal* aPrincipal)
|
||||
{
|
||||
return mFontFaceSet &&
|
||||
mFontFaceSet->IsFontLoadAllowed(aFontLocation, aPrincipal);
|
||||
}
|
||||
|
||||
/* virtual */ nsresult
|
||||
FontFaceSet::UserFontSet::StartLoad(gfxUserFontEntry* aUserFontEntry,
|
||||
const gfxFontFaceSrc* aFontFaceSrc)
|
||||
|
|
|
@ -64,6 +64,10 @@ public:
|
|||
virtual nsresult CheckFontLoad(const gfxFontFaceSrc* aFontFaceSrc,
|
||||
nsIPrincipal** aPrincipal,
|
||||
bool* aBypassCache) override;
|
||||
|
||||
virtual bool IsFontLoadAllowed(nsIURI* aFontLocation,
|
||||
nsIPrincipal* aPrincipal) override;
|
||||
|
||||
virtual nsresult StartLoad(gfxUserFontEntry* aUserFontEntry,
|
||||
const gfxFontFaceSrc* aFontFaceSrc) override;
|
||||
|
||||
|
@ -256,6 +260,7 @@ private:
|
|||
nsresult CheckFontLoad(const gfxFontFaceSrc* aFontFaceSrc,
|
||||
nsIPrincipal** aPrincipal,
|
||||
bool* aBypassCache);
|
||||
bool IsFontLoadAllowed(nsIURI* aFontLocation, nsIPrincipal* aPrincipal);
|
||||
bool GetPrivateBrowsing();
|
||||
nsresult SyncLoadFontData(gfxUserFontEntry* aFontToLoad,
|
||||
const gfxFontFaceSrc* aFontFaceSrc,
|
||||
|
|
|
@ -297,43 +297,6 @@ nsFontFaceLoader::Cancel()
|
|||
mChannel->Cancel(NS_BINDING_ABORTED);
|
||||
}
|
||||
|
||||
/* static */ nsresult
|
||||
nsFontFaceLoader::CheckLoadAllowed(nsIPrincipal* aSourcePrincipal,
|
||||
nsIURI* aTargetURI,
|
||||
nsISupports* aContext)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
if (!aSourcePrincipal)
|
||||
return NS_OK;
|
||||
|
||||
// check with the security manager
|
||||
nsIScriptSecurityManager* secMan = nsContentUtils::GetSecurityManager();
|
||||
rv = secMan->CheckLoadURIWithPrincipal(aSourcePrincipal, aTargetURI,
|
||||
nsIScriptSecurityManager::STANDARD);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
// check content policy
|
||||
int16_t shouldLoad = nsIContentPolicy::ACCEPT;
|
||||
rv = NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_FONT,
|
||||
aTargetURI,
|
||||
aSourcePrincipal,
|
||||
aContext,
|
||||
EmptyCString(), // mime type
|
||||
nullptr,
|
||||
&shouldLoad,
|
||||
nsContentUtils::GetContentPolicy(),
|
||||
nsContentUtils::GetSecurityManager());
|
||||
|
||||
if (NS_FAILED(rv) || NS_CP_REJECTED(shouldLoad)) {
|
||||
return NS_ERROR_CONTENT_BLOCKED;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
nsFontFaceLoader::GetFontDisplay()
|
||||
{
|
||||
|
|
|
@ -42,9 +42,6 @@ public:
|
|||
|
||||
static void LoadTimerCallback(nsITimer* aTimer, void* aClosure);
|
||||
|
||||
static nsresult CheckLoadAllowed(nsIPrincipal* aSourcePrincipal,
|
||||
nsIURI* aTargetURI,
|
||||
nsISupports* aContext);
|
||||
gfxUserFontEntry* GetUserFontEntry() const { return mUserFontEntry; }
|
||||
|
||||
protected:
|
||||
|
|
Загрузка…
Ссылка в новой задаче