Bug 732209 part 4. Propagate the CORS state throughout the CSS loading process. r=sicking,dbaron

This commit is contained in:
Boris Zbarsky 2012-08-28 13:10:08 -04:00
parent b958f016c5
commit f6bb4154ad
6 changed files with 81 additions and 52 deletions

View File

@ -1120,7 +1120,7 @@ nsTreeSanitizer::SanitizeStyleSheet(const nsAString& aOriginal,
// -moz-binding is blacklisted.
bool didSanitize = false;
// Create a sheet to hold the parsed CSS
nsRefPtr<nsCSSStyleSheet> sheet = new nsCSSStyleSheet();
nsRefPtr<nsCSSStyleSheet> sheet = new nsCSSStyleSheet(CORS_NONE);
sheet->SetURIs(aDocument->GetDocumentURI(), nullptr, aBaseURI);
sheet->SetPrincipal(aDocument->NodePrincipal());
// Create the CSS parser, and parse the CSS text.

View File

@ -1206,7 +1206,7 @@ PresShell::CreatePreferenceStyleSheet()
NS_TIME_FUNCTION_MIN(1.0);
NS_ASSERTION(!mPrefStyleSheet, "prefStyleSheet already exists");
mPrefStyleSheet = new nsCSSStyleSheet();
mPrefStyleSheet = new nsCSSStyleSheet(CORS_NONE);
nsCOMPtr<nsIURI> uri;
nsresult rv = NS_NewURI(getter_AddRefs(uri), "about:PreferenceStyleSheet", nullptr);
if (NS_FAILED(rv)) {

View File

@ -553,7 +553,7 @@ Loader::DropDocumentReference(void)
}
static PLDHashOperator
CollectNonAlternates(URIAndPrincipalHashKey *aKey,
CollectNonAlternates(URIPrincipalAndCORSModeHashKey *aKey,
SheetLoadData* &aData,
void* aClosure)
{
@ -1060,6 +1060,7 @@ nsresult
Loader::CreateSheet(nsIURI* aURI,
nsIContent* aLinkingContent,
nsIPrincipal* aLoaderPrincipal,
CORSMode aCORSMode,
bool aSyncLoad,
bool aHasAlternateRel,
const nsAString& aTitle,
@ -1106,7 +1107,7 @@ Loader::CreateSheet(nsIURI* aURI,
if (!sheet) {
// Then our per-document complete sheets.
URIAndPrincipalHashKey key(aURI, aLoaderPrincipal);
URIPrincipalAndCORSModeHashKey key(aURI, aLoaderPrincipal, aCORSMode);
mCompleteSheets.Get(&key, getter_AddRefs(sheet));
LOG((" From completed: %p", sheet.get()));
@ -1130,7 +1131,7 @@ Loader::CreateSheet(nsIURI* aURI,
if (!sheet && !aSyncLoad) {
aSheetState = eSheetLoading;
SheetLoadData* loadData = nullptr;
URIAndPrincipalHashKey key(aURI, aLoaderPrincipal);
URIPrincipalAndCORSModeHashKey key(aURI, aLoaderPrincipal, aCORSMode);
mLoadingDatas.Get(&key, &loadData);
if (loadData) {
sheet = loadData->mSheet;
@ -1198,7 +1199,7 @@ Loader::CreateSheet(nsIURI* aURI,
originalURI = aURI;
}
nsRefPtr<nsCSSStyleSheet> sheet = new nsCSSStyleSheet();
nsRefPtr<nsCSSStyleSheet> sheet = new nsCSSStyleSheet(aCORSMode);
sheet->SetURIs(sheetURI, originalURI, baseURI);
sheet.forget(aSheet);
}
@ -1450,7 +1451,9 @@ Loader::LoadSheet(SheetLoadData* aLoadData, StyleSheetState aSheetState)
SheetLoadData* existingData = nullptr;
URIAndPrincipalHashKey key(aLoadData->mURI, aLoadData->mLoaderPrincipal);
URIPrincipalAndCORSModeHashKey key(aLoadData->mURI,
aLoadData->mLoaderPrincipal,
aLoadData->mSheet->GetCORSMode());
if (aSheetState == eSheetLoading) {
mLoadingDatas.Get(&key, &existingData);
NS_ASSERTION(existingData, "CreateSheet lied about the state");
@ -1696,8 +1699,9 @@ Loader::DoSheetComplete(SheetLoadData* aLoadData, nsresult aStatus,
LOG_URI(" Finished loading: '%s'", aLoadData->mURI);
// Remove the data from the list of loading datas
if (aLoadData->mIsLoading) {
URIAndPrincipalHashKey key(aLoadData->mURI,
aLoadData->mLoaderPrincipal);
URIPrincipalAndCORSModeHashKey key(aLoadData->mURI,
aLoadData->mLoaderPrincipal,
aLoadData->mSheet->GetCORSMode());
#ifdef DEBUG
SheetLoadData *loadingData;
NS_ASSERTION(mLoadingDatas.Get(&key, &loadingData) &&
@ -1766,8 +1770,9 @@ Loader::DoSheetComplete(SheetLoadData* aLoadData, nsresult aStatus,
}
else {
#endif
URIAndPrincipalHashKey key(aLoadData->mURI,
aLoadData->mLoaderPrincipal);
URIPrincipalAndCORSModeHashKey key(aLoadData->mURI,
aLoadData->mLoaderPrincipal,
aLoadData->mSheet->GetCORSMode());
mCompleteSheets.Put(&key, aLoadData->mSheet);
#ifdef MOZ_XUL
}
@ -1803,10 +1808,11 @@ Loader::LoadInlineStyle(nsIContent* aElement,
NS_ASSERTION(owningElement, "Element is not a style linking element!");
// Since we're not planning to load a URI, no need to hand a principal to the
// load data or to CreateSheet().
// load data or to CreateSheet(). Also, OK to use CORS_NONE for the CORS
// mode.
StyleSheetState state;
nsRefPtr<nsCSSStyleSheet> sheet;
nsresult rv = CreateSheet(nullptr, aElement, nullptr, false, false,
nsresult rv = CreateSheet(nullptr, aElement, nullptr, CORS_NONE, false, false,
aTitle, state, aIsAlternate, getter_AddRefs(sheet));
NS_ENSURE_SUCCESS(rv, rv);
NS_ASSERTION(state == eSheetNeedsParser,
@ -1880,8 +1886,9 @@ Loader::LoadStyleLink(nsIContent* aElement,
StyleSheetState state;
nsRefPtr<nsCSSStyleSheet> sheet;
rv = CreateSheet(aURL, aElement, principal, false, aHasAlternateRel,
aTitle, state, aIsAlternate, getter_AddRefs(sheet));
rv = CreateSheet(aURL, aElement, principal, aCORSMode, false,
aHasAlternateRel, aTitle, state, aIsAlternate,
getter_AddRefs(sheet));
NS_ENSURE_SUCCESS(rv, rv);
LOG((" Sheet is alternate: %d", *aIsAlternate));
@ -1916,7 +1923,8 @@ Loader::LoadStyleLink(nsIContent* aElement,
if (aURL && state == eSheetNeedsParser && mLoadingDatas.Count() != 0 &&
*aIsAlternate) {
LOG((" Deferring alternate sheet load"));
URIAndPrincipalHashKey key(data->mURI, data->mLoaderPrincipal);
URIPrincipalAndCORSModeHashKey key(data->mURI, data->mLoaderPrincipal,
data->mSheet->GetCORSMode());
mPendingDatas.Put(&key, data);
data->mMustNotify = true;
@ -2032,12 +2040,13 @@ Loader::LoadChildSheet(nsCSSStyleSheet* aParentSheet,
}
// Now that we know it's safe to load this (passes security check and not a
// loop) do so
// loop) do so.
nsRefPtr<nsCSSStyleSheet> sheet;
bool isAlternate;
StyleSheetState state;
const nsSubstring& empty = EmptyString();
rv = CreateSheet(aURL, nullptr, principal,
// For now, use CORS_NONE for child sheets
rv = CreateSheet(aURL, nullptr, principal, CORS_NONE,
parentData ? parentData->mSyncLoad : false,
false, empty, state, &isAlternate, getter_AddRefs(sheet));
NS_ENSURE_SUCCESS(rv, rv);
@ -2149,8 +2158,8 @@ Loader::InternalLoadNonDocumentSheet(nsIURI* aURL,
bool syncLoad = (aObserver == nullptr);
const nsSubstring& empty = EmptyString();
rv = CreateSheet(aURL, nullptr, aOriginPrincipal, syncLoad, false, empty,
state, &isAlternate, getter_AddRefs(sheet));
rv = CreateSheet(aURL, nullptr, aOriginPrincipal, aCORSMode, syncLoad, false,
empty, state, &isAlternate, getter_AddRefs(sheet));
NS_ENSURE_SUCCESS(rv, rv);
rv = PrepareSheet(sheet, empty, empty, nullptr, isAlternate);
@ -2262,7 +2271,7 @@ Loader::HandleLoadEvent(SheetLoadData* aEvent)
}
static PLDHashOperator
StopLoadingSheetCallback(URIAndPrincipalHashKey* aKey,
StopLoadingSheetCallback(URIPrincipalAndCORSModeHashKey* aKey,
SheetLoadData*& aData,
void* aClosure)
{
@ -2346,7 +2355,7 @@ Loader::RemoveObserver(nsICSSLoaderObserver* aObserver)
}
static PLDHashOperator
CollectLoadDatas(URIAndPrincipalHashKey *aKey,
CollectLoadDatas(URIPrincipalAndCORSModeHashKey *aKey,
SheetLoadData* &aData,
void* aClosure)
{

View File

@ -32,38 +32,41 @@ class nsIStyleSheetLinkingElement;
namespace mozilla {
class URIAndPrincipalHashKey : public nsURIHashKey
class URIPrincipalAndCORSModeHashKey : public nsURIHashKey
{
public:
typedef URIAndPrincipalHashKey* KeyType;
typedef const URIAndPrincipalHashKey* KeyTypePointer;
typedef URIPrincipalAndCORSModeHashKey* KeyType;
typedef const URIPrincipalAndCORSModeHashKey* KeyTypePointer;
URIAndPrincipalHashKey(const URIAndPrincipalHashKey* aKey)
: nsURIHashKey(aKey->mKey), mPrincipal(aKey->mPrincipal)
URIPrincipalAndCORSModeHashKey(const URIPrincipalAndCORSModeHashKey* aKey)
: nsURIHashKey(aKey->mKey), mPrincipal(aKey->mPrincipal),
mCORSMode(aKey->mCORSMode)
{
MOZ_COUNT_CTOR(URIAndPrincipalHashKey);
MOZ_COUNT_CTOR(URIPrincipalAndCORSModeHashKey);
}
URIAndPrincipalHashKey(nsIURI* aURI, nsIPrincipal* aPrincipal)
: nsURIHashKey(aURI), mPrincipal(aPrincipal)
URIPrincipalAndCORSModeHashKey(nsIURI* aURI, nsIPrincipal* aPrincipal,
CORSMode aCORSMode)
: nsURIHashKey(aURI), mPrincipal(aPrincipal), mCORSMode(aCORSMode)
{
MOZ_COUNT_CTOR(URIAndPrincipalHashKey);
MOZ_COUNT_CTOR(URIPrincipalAndCORSModeHashKey);
}
URIAndPrincipalHashKey(const URIAndPrincipalHashKey& toCopy)
: nsURIHashKey(toCopy), mPrincipal(toCopy.mPrincipal)
URIPrincipalAndCORSModeHashKey(const URIPrincipalAndCORSModeHashKey& toCopy)
: nsURIHashKey(toCopy), mPrincipal(toCopy.mPrincipal),
mCORSMode(toCopy.mCORSMode)
{
MOZ_COUNT_CTOR(URIAndPrincipalHashKey);
MOZ_COUNT_CTOR(URIPrincipalAndCORSModeHashKey);
}
~URIAndPrincipalHashKey()
~URIPrincipalAndCORSModeHashKey()
{
MOZ_COUNT_DTOR(URIAndPrincipalHashKey);
MOZ_COUNT_DTOR(URIPrincipalAndCORSModeHashKey);
}
URIAndPrincipalHashKey* GetKey() const {
return const_cast<URIAndPrincipalHashKey*>(this);
URIPrincipalAndCORSModeHashKey* GetKey() const {
return const_cast<URIPrincipalAndCORSModeHashKey*>(this);
}
const URIAndPrincipalHashKey* GetKeyPointer() const { return this; }
const URIPrincipalAndCORSModeHashKey* GetKeyPointer() const { return this; }
bool KeyEquals(const URIAndPrincipalHashKey* aKey) const {
bool KeyEquals(const URIPrincipalAndCORSModeHashKey* aKey) const {
if (!nsURIHashKey::KeyEquals(aKey->mKey)) {
return false;
}
@ -73,14 +76,19 @@ public:
return false;
}
if (mCORSMode != aKey->mCORSMode) {
// Different CORS modes; we don't match
return false;
}
bool eq;
return !mPrincipal ||
(NS_SUCCEEDED(mPrincipal->Equals(aKey->mPrincipal, &eq)) && eq);
}
static const URIAndPrincipalHashKey*
KeyToPointer(URIAndPrincipalHashKey* aKey) { return aKey; }
static PLDHashNumber HashKey(const URIAndPrincipalHashKey* aKey) {
static const URIPrincipalAndCORSModeHashKey*
KeyToPointer(URIPrincipalAndCORSModeHashKey* aKey) { return aKey; }
static PLDHashNumber HashKey(const URIPrincipalAndCORSModeHashKey* aKey) {
return nsURIHashKey::HashKey(aKey->mKey);
}
@ -88,6 +96,7 @@ public:
protected:
nsCOMPtr<nsIPrincipal> mPrincipal;
CORSMode mCORSMode;
};
@ -361,6 +370,7 @@ private:
nsresult CreateSheet(nsIURI* aURI,
nsIContent* aLinkingContent,
nsIPrincipal* aLoaderPrincipal,
CORSMode aCORSMode,
bool aSyncLoad,
bool aHasAlternateRel,
const nsAString& aTitle,
@ -435,11 +445,11 @@ private:
void DoSheetComplete(SheetLoadData* aLoadData, nsresult aStatus,
LoadDataArray& aDatasToNotify);
nsRefPtrHashtable<URIAndPrincipalHashKey, nsCSSStyleSheet>
nsRefPtrHashtable<URIPrincipalAndCORSModeHashKey, nsCSSStyleSheet>
mCompleteSheets;
nsDataHashtable<URIAndPrincipalHashKey, SheetLoadData*>
nsDataHashtable<URIPrincipalAndCORSModeHashKey, SheetLoadData*>
mLoadingDatas; // weak refs
nsDataHashtable<URIAndPrincipalHashKey, SheetLoadData*>
nsDataHashtable<URIPrincipalAndCORSModeHashKey, SheetLoadData*>
mPendingDatas; // weak refs
// We're not likely to have many levels of @import... But likely to have

View File

@ -39,7 +39,8 @@
#include "nsMediaFeatures.h"
#include "nsDOMClassInfoID.h"
namespace css = mozilla::css;
using namespace mozilla;
// -------------------------------
// Style Rule List for the DOM
@ -763,8 +764,10 @@ nsMediaList::Append(const nsAString& aNewMedium)
//
nsCSSStyleSheetInner::nsCSSStyleSheetInner(nsCSSStyleSheet* aPrimarySheet)
nsCSSStyleSheetInner::nsCSSStyleSheetInner(nsCSSStyleSheet* aPrimarySheet,
CORSMode aCORSMode)
: mSheets(),
mCORSMode(aCORSMode),
mComplete(false)
#ifdef DEBUG
, mPrincipalSet(false)
@ -884,6 +887,7 @@ nsCSSStyleSheetInner::nsCSSStyleSheetInner(nsCSSStyleSheetInner& aCopy,
mOriginalSheetURI(aCopy.mOriginalSheetURI),
mBaseURI(aCopy.mBaseURI),
mPrincipal(aCopy.mPrincipal),
mCORSMode(aCopy.mCORSMode),
mComplete(aCopy.mComplete)
#ifdef DEBUG
, mPrincipalSet(aCopy.mPrincipalSet)
@ -1012,7 +1016,7 @@ nsCSSStyleSheetInner::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const
// CSS Style Sheet
//
nsCSSStyleSheet::nsCSSStyleSheet()
nsCSSStyleSheet::nsCSSStyleSheet(CORSMode aCORSMode)
: mTitle(),
mParent(nullptr),
mOwnerRule(nullptr),
@ -1024,7 +1028,7 @@ nsCSSStyleSheet::nsCSSStyleSheet()
mRuleProcessors(nullptr)
{
mInner = new nsCSSStyleSheetInner(this);
mInner = new nsCSSStyleSheetInner(this, aCORSMode);
}
nsCSSStyleSheet::nsCSSStyleSheet(const nsCSSStyleSheet& aCopy,

View File

@ -20,6 +20,7 @@
#include "nsCOMArray.h"
#include "nsTArray.h"
#include "nsString.h"
#include "mozilla/CORSMode.h"
class nsXMLNameSpaceMap;
class nsCSSRuleProcessor;
@ -49,7 +50,8 @@ public:
friend class nsCSSStyleSheet;
friend class nsCSSRuleProcessor;
private:
nsCSSStyleSheetInner(nsCSSStyleSheet* aPrimarySheet);
nsCSSStyleSheetInner(nsCSSStyleSheet* aPrimarySheet,
mozilla::CORSMode aCORSMode);
nsCSSStyleSheetInner(nsCSSStyleSheetInner& aCopy,
nsCSSStyleSheet* aPrimarySheet);
~nsCSSStyleSheetInner();
@ -78,6 +80,7 @@ private:
// child sheet that means we've already ensured unique inners throughout its
// parent chain and things are good.
nsRefPtr<nsCSSStyleSheet> mFirstChild;
mozilla::CORSMode mCORSMode;
bool mComplete;
#ifdef DEBUG
@ -105,7 +108,7 @@ class nsCSSStyleSheet MOZ_FINAL : public nsIStyleSheet,
public nsICSSLoaderObserver
{
public:
nsCSSStyleSheet();
nsCSSStyleSheet(mozilla::CORSMode aCORSMode);
NS_DECL_ISUPPORTS
@ -239,6 +242,9 @@ public:
size_t SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const;
// Get this style sheet's CORS mode
mozilla::CORSMode GetCORSMode() const { return mInner->mCORSMode; }
private:
nsCSSStyleSheet(const nsCSSStyleSheet& aCopy,
nsCSSStyleSheet* aParentToUse,