bug 1030067 - ignore the principal when caching data-URI fonts, to allow sharing across pages with the same CSS. r=bzbarsky

This commit is contained in:
Jonathan Kew 2014-06-27 16:19:28 +01:00
parent e8e1794003
commit 0b1642e471
2 changed files with 58 additions and 22 deletions

View File

@ -876,16 +876,32 @@ gfxUserFontSet::UserFontCache::Flusher::Observe(nsISupports* aSubject,
return NS_OK;
}
static bool
IgnorePrincipal(nsIURI *aURI)
{
nsresult rv;
bool inherits = false;
rv = NS_URIChainHasFlags(aURI,
nsIProtocolHandler::URI_INHERITS_SECURITY_CONTEXT,
&inherits);
return NS_SUCCEEDED(rv) && inherits;
}
bool
gfxUserFontSet::UserFontCache::Entry::KeyEquals(const KeyTypePointer aKey) const
{
bool equal;
if (NS_FAILED(mURI->Equals(aKey->mURI, &equal)) || !equal) {
bool result;
if (NS_FAILED(mURI->Equals(aKey->mURI, &result)) || !result) {
return false;
}
if (NS_FAILED(mPrincipal->Equals(aKey->mPrincipal, &equal)) || !equal) {
return false;
// For data: URIs, we don't care about the principal; otherwise, check it.
if (!IgnorePrincipal(mURI)) {
NS_ASSERTION(mPrincipal && aKey->mPrincipal,
"only data: URIs are allowed to omit the principal");
if (NS_FAILED(mPrincipal->Equals(aKey->mPrincipal, &result)) || !result) {
return false;
}
}
if (mPrivate != aKey->mPrivate) {
@ -925,7 +941,16 @@ gfxUserFontSet::UserFontCache::CacheFont(gfxFontEntry *aFontEntry)
}
gfxUserFontData *data = aFontEntry->mUserFontData;
sUserFonts->PutEntry(Key(data->mURI, data->mPrincipal, aFontEntry,
// For data: URIs, the principal is ignored; anyone who has the same
// data: URI is able to load it and get an equivalent font.
// Otherwise, the principal is used as part of the cache key.
nsIPrincipal *principal;
if (IgnorePrincipal(data->mURI)) {
principal = nullptr;
} else {
principal = data->mPrincipal;
}
sUserFonts->PutEntry(Key(data->mURI, principal, aFontEntry,
data->mPrivate));
#ifdef DEBUG_USERFONT_CACHE
@ -965,7 +990,15 @@ gfxUserFontSet::UserFontCache::GetFont(nsIURI *aSrcURI,
return nullptr;
}
Entry* entry = sUserFonts->GetEntry(Key(aSrcURI, aPrincipal, aProxy,
// Ignore principal when looking up a data: URI.
nsIPrincipal *principal;
if (IgnorePrincipal(aSrcURI)) {
principal = nullptr;
} else {
principal = aPrincipal;
}
Entry* entry = sUserFonts->GetEntry(Key(aSrcURI, principal, aProxy,
aPrivate));
if (entry) {
return entry->GetFontEntry();
@ -990,20 +1023,21 @@ gfxUserFontSet::UserFontCache::Entry::DumpEntry(Entry* aEntry, void* aUserData)
{
nsresult rv;
nsAutoCString principalURISpec;
nsCOMPtr<nsIURI> principalURI;
rv = aEntry->mPrincipal->GetURI(getter_AddRefs(principalURI));
if (NS_SUCCEEDED(rv)) {
principalURI->GetSpec(principalURISpec);
}
nsAutoCString principalURISpec("(null)");
bool setDomain = false;
nsCOMPtr<nsIURI> domainURI;
aEntry->mPrincipal->GetDomain(getter_AddRefs(domainURI));
if (domainURI) {
setDomain = true;
if (aEntry->mPrincipal) {
nsCOMPtr<nsIURI> principalURI;
rv = aEntry->mPrincipal->GetURI(getter_AddRefs(principalURI));
if (NS_SUCCEEDED(rv)) {
principalURI->GetSpec(principalURISpec);
}
nsCOMPtr<nsIURI> domainURI;
aEntry->mPrincipal->GetDomain(getter_AddRefs(domainURI));
if (domainURI) {
setDomain = true;
}
}
NS_ASSERTION(aEntry->mURI, "null URI in userfont cache entry");

View File

@ -294,7 +294,7 @@ public:
// entry and the corresponding "real" font entry.
struct Key {
nsCOMPtr<nsIURI> mURI;
nsCOMPtr<nsIPrincipal> mPrincipal;
nsCOMPtr<nsIPrincipal> mPrincipal; // use nullptr with data: URLs
gfxFontEntry *mFontEntry;
bool mPrivate;
@ -333,8 +333,10 @@ public:
static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; }
static PLDHashNumber HashKey(const KeyTypePointer aKey) {
uint32_t principalHash;
aKey->mPrincipal->GetHashValue(&principalHash);
uint32_t principalHash = 0;
if (aKey->mPrincipal) {
aKey->mPrincipal->GetHashValue(&principalHash);
}
return mozilla::HashGeneric(principalHash + int(aKey->mPrivate),
nsURIHashKey::HashKey(aKey->mURI),
HashFeatures(aKey->mFontEntry->mFeatureSettings),
@ -365,7 +367,7 @@ public:
}
nsCOMPtr<nsIURI> mURI;
nsCOMPtr<nsIPrincipal> mPrincipal;
nsCOMPtr<nsIPrincipal> mPrincipal; // or nullptr for data: URLs
// The "real" font entry corresponding to this downloaded font.
// The font entry MUST notify the cache when it is destroyed