From 0b1642e4713f23f88eec98aeeb939d4c6f17ee4d Mon Sep 17 00:00:00 2001 From: Jonathan Kew Date: Fri, 27 Jun 2014 16:19:28 +0100 Subject: [PATCH] bug 1030067 - ignore the principal when caching data-URI fonts, to allow sharing across pages with the same CSS. r=bzbarsky --- gfx/thebes/gfxUserFontSet.cpp | 70 ++++++++++++++++++++++++++--------- gfx/thebes/gfxUserFontSet.h | 10 +++-- 2 files changed, 58 insertions(+), 22 deletions(-) diff --git a/gfx/thebes/gfxUserFontSet.cpp b/gfx/thebes/gfxUserFontSet.cpp index 8fbc908b7c5..487efac812b 100644 --- a/gfx/thebes/gfxUserFontSet.cpp +++ b/gfx/thebes/gfxUserFontSet.cpp @@ -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 principalURI; - rv = aEntry->mPrincipal->GetURI(getter_AddRefs(principalURI)); - if (NS_SUCCEEDED(rv)) { - principalURI->GetSpec(principalURISpec); - } - + nsAutoCString principalURISpec("(null)"); bool setDomain = false; - nsCOMPtr domainURI; - aEntry->mPrincipal->GetDomain(getter_AddRefs(domainURI)); - if (domainURI) { - setDomain = true; + if (aEntry->mPrincipal) { + nsCOMPtr principalURI; + rv = aEntry->mPrincipal->GetURI(getter_AddRefs(principalURI)); + if (NS_SUCCEEDED(rv)) { + principalURI->GetSpec(principalURISpec); + } + + nsCOMPtr domainURI; + aEntry->mPrincipal->GetDomain(getter_AddRefs(domainURI)); + if (domainURI) { + setDomain = true; + } } NS_ASSERTION(aEntry->mURI, "null URI in userfont cache entry"); diff --git a/gfx/thebes/gfxUserFontSet.h b/gfx/thebes/gfxUserFontSet.h index f5068a8c4db..446e236ee88 100644 --- a/gfx/thebes/gfxUserFontSet.h +++ b/gfx/thebes/gfxUserFontSet.h @@ -294,7 +294,7 @@ public: // entry and the corresponding "real" font entry. struct Key { nsCOMPtr mURI; - nsCOMPtr mPrincipal; + nsCOMPtr 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 mURI; - nsCOMPtr mPrincipal; + nsCOMPtr 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