From 6e86d03b2e2dd09bbbeadb82a2e065eee4277156 Mon Sep 17 00:00:00 2001 From: "bzbarsky%mit.edu" Date: Tue, 1 May 2007 19:26:15 +0000 Subject: [PATCH] Stylesheets should know what their principal is, and it should be based on the URI the sheet was loaded from, its certificate (if any) and the loader principal, not just on the page the sheet is being applied to. Propagate this principal as the loading principal to @import loads from stylesheets. Change sheet access checks to use this principal instead of the sheet URI. Bug 221428, r+sr=peterv git-svn-id: svn://10.0.0.236/trunk@225401 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/layout/style/nsCSSLoader.cpp | 303 ++++++++++++------ mozilla/layout/style/nsCSSLoader.h | 81 ++++- mozilla/layout/style/nsCSSStyleSheet.cpp | 187 +++++------ mozilla/layout/style/nsCSSStyleSheet.h | 10 +- mozilla/layout/style/nsICSSStyleSheet.h | 17 +- mozilla/layout/style/test/Makefile.in | 3 +- mozilla/layout/style/test/test_bug221428.html | 69 ++++ mozilla/netwerk/base/public/nsURIHashKey.h | 2 +- 8 files changed, 476 insertions(+), 196 deletions(-) create mode 100644 mozilla/layout/style/test/test_bug221428.html diff --git a/mozilla/layout/style/nsCSSLoader.cpp b/mozilla/layout/style/nsCSSLoader.cpp index 4a65f36828e..c2f844d7e22 100644 --- a/mozilla/layout/style/nsCSSLoader.cpp +++ b/mozilla/layout/style/nsCSSLoader.cpp @@ -147,7 +147,8 @@ SheetLoadData::SheetLoadData(CSSLoaderImpl* aLoader, nsICSSStyleSheet* aSheet, nsIStyleSheetLinkingElement* aOwningElement, PRBool aIsAlternate, - nsICSSLoaderObserver* aObserver) + nsICSSLoaderObserver* aObserver, + nsIPrincipal* aLoaderPrincipal) : mLoader(aLoader), mTitle(aTitle), mURI(aURI), @@ -164,7 +165,8 @@ SheetLoadData::SheetLoadData(CSSLoaderImpl* aLoader, mWasAlternate(aIsAlternate), mAllowUnsafeRules(PR_FALSE), mOwningElement(aOwningElement), - mObserver(aObserver) + mObserver(aObserver), + mLoaderPrincipal(aLoaderPrincipal) { NS_PRECONDITION(mLoader, "Must have a loader!"); @@ -175,7 +177,8 @@ SheetLoadData::SheetLoadData(CSSLoaderImpl* aLoader, nsIURI* aURI, nsICSSStyleSheet* aSheet, SheetLoadData* aParentData, - nsICSSLoaderObserver* aObserver) + nsICSSLoaderObserver* aObserver, + nsIPrincipal* aLoaderPrincipal) : mLoader(aLoader), mURI(aURI), mLineNumber(1), @@ -191,7 +194,8 @@ SheetLoadData::SheetLoadData(CSSLoaderImpl* aLoader, mWasAlternate(PR_FALSE), mAllowUnsafeRules(PR_FALSE), mOwningElement(nsnull), - mObserver(aObserver) + mObserver(aObserver), + mLoaderPrincipal(aLoaderPrincipal) { NS_PRECONDITION(mLoader, "Must have a loader!"); @@ -226,7 +230,8 @@ SheetLoadData::SheetLoadData(CSSLoaderImpl* aLoader, mWasAlternate(PR_FALSE), mAllowUnsafeRules(aAllowUnsafeRules), mOwningElement(nsnull), - mObserver(aObserver) + mObserver(aObserver), + mLoaderPrincipal(nsnull) { NS_PRECONDITION(mLoader, "Must have a loader!"); @@ -300,7 +305,9 @@ CSSLoaderImpl::Init(nsIDocument* aDocument) } PR_STATIC_CALLBACK(PLDHashOperator) -StartAlternateLoads(nsIURI *aKey, SheetLoadData* &aData, void* aClosure) +StartAlternateLoads(nsURIAndPrincipalHashKey *aKey, + SheetLoadData* &aData, + void* aClosure) { NS_STATIC_CAST(CSSLoaderImpl*,aClosure)->LoadSheet(aData, eSheetNeedsParser); return PL_DHASH_REMOVE; @@ -333,7 +340,9 @@ CSSLoaderImpl::SetCompatibilityMode(nsCompatibility aCompatMode) } PR_STATIC_CALLBACK(PLDHashOperator) -StartNonAlternates(nsIURI *aKey, SheetLoadData* &aData, void* aClosure) +StartNonAlternates(nsURIAndPrincipalHashKey *aKey, + SheetLoadData* &aData, + void* aClosure) { NS_PRECONDITION(aData, "Must have a data"); NS_PRECONDITION(aClosure, "Must have a loader"); @@ -753,23 +762,53 @@ SheetLoadData::OnStreamComplete(nsIUnicharStreamLoader* aLoader, return NS_OK; } + if (NS_FAILED(aStatus)) { + LOG_WARN((" Load failed: status 0x%x", aStatus)); + mLoader->SheetComplete(this, aStatus); + return NS_OK; + } + nsCOMPtr channel; nsresult result = aLoader->GetChannel(getter_AddRefs(channel)); - if (NS_FAILED(result)) - channel = nsnull; + if (NS_FAILED(result)) { + LOG_WARN((" No channel from loader")); + mLoader->SheetComplete(this, result); + return NS_OK; + } nsCOMPtr channelURI; - if (channel) { - // If the channel's original URI is "chrome:", we want that, since - // the observer code in nsXULPrototypeCache depends on chrome stylesheets - // having a chrome URI. (Whether or not chrome stylesheets come through - // this codepath seems nondeterministic.) - // Otherwise we want the potentially-HTTP-redirected URI. - channel->GetOriginalURI(getter_AddRefs(channelURI)); - PRBool isChrome; - if (NS_FAILED(channelURI->SchemeIs("chrome", &isChrome)) || !isChrome) - channel->GetURI(getter_AddRefs(channelURI)); + // If the channel's original URI is "chrome:", we want that, since + // the observer code in nsXULPrototypeCache depends on chrome stylesheets + // having a chrome URI. (Whether or not chrome stylesheets come through + // this codepath seems nondeterministic.) + // Otherwise we want the potentially-HTTP-redirected URI. + channel->GetOriginalURI(getter_AddRefs(channelURI)); + PRBool isChrome; + if (NS_FAILED(channelURI->SchemeIs("chrome", &isChrome)) || !isChrome) { + channel->GetURI(getter_AddRefs(channelURI)); } + + if (!channelURI) { + NS_ERROR("Someone just violated the nsIRequest contract"); + LOG_WARN((" Channel without a URI. Bad!")); + mLoader->SheetComplete(this, NS_ERROR_UNEXPECTED); + return NS_OK; + } + + nsCOMPtr principal; + nsIScriptSecurityManager* secMan = nsContentUtils::GetSecurityManager(); + result = NS_ERROR_NOT_AVAILABLE; + if (secMan) { // Could be null if we already shut down + result = secMan->GetChannelPrincipal(channel, getter_AddRefs(principal)); + } + + if (NS_FAILED(result)) { + LOG_WARN((" Couldn't get principal")); + mLoader->SheetComplete(this, result); + return NS_OK; + } + + mSheet->SetPrincipal(principal); #ifdef MOZ_TIMELINE NS_TIMELINE_OUTDENT(); @@ -801,9 +840,7 @@ SheetLoadData::OnStreamComplete(nsIUnicharStreamLoader* aLoader, if (!validType) { nsCAutoString spec; - if (channelURI) { - channelURI->GetSpec(spec); - } + channelURI->GetSpec(spec); const nsAFlatString& specUTF16 = NS_ConvertUTF8toUTF16(spec); const nsAFlatString& ctypeUTF16 = NS_ConvertASCIItoUTF16(contentType); @@ -831,23 +868,15 @@ SheetLoadData::OnStreamComplete(nsIUnicharStreamLoader* aLoader, } } - if (NS_FAILED(aStatus)) { - LOG_WARN((" Load failed: status 0x%x", aStatus)); - mLoader->SheetComplete(this, aStatus); - return NS_OK; - } - if (!aDataStream) { LOG_WARN((" No data stream; bailing")); mLoader->SheetComplete(this, NS_ERROR_NOT_AVAILABLE); return NS_OK; } - if (channelURI) { - // Enough to set the URI on mSheet, since any sibling datas we have share - // the same mInner as mSheet and will thus get the same URI. - mSheet->SetURIs(channelURI, channelURI); - } + // Enough to set the URI on mSheet, since any sibling datas we have share + // the same mInner as mSheet and will thus get the same URI. + mSheet->SetURIs(channelURI, channelURI); PRBool completed; return mLoader->ParseSheet(aDataStream, this, completed); @@ -891,12 +920,15 @@ CSSLoaderImpl::IsAlternate(const nsAString& aTitle, PRBool aHasAlternateRel) * failure otherwise. * * @param aSourceURI the uri of the document or parent sheet loading the sheet + * @param aSourcePrincipal the principal of the node or document or parent + * sheet loading the sheet * @param aTargetURI the uri of the sheet to be loaded * @param aContext the node owning the sheet. This is the element or document * owning the stylesheet (possibly indirectly, for child sheets) */ nsresult CSSLoaderImpl::CheckLoadAllowed(nsIURI* aSourceURI, + nsIPrincipal* aSourcePrincipal, nsIURI* aTargetURI, nsISupports* aContext) { @@ -904,8 +936,9 @@ CSSLoaderImpl::CheckLoadAllowed(nsIURI* aSourceURI, // Check with the security manager nsIScriptSecurityManager *secMan = nsContentUtils::GetSecurityManager(); - nsresult rv = secMan->CheckLoadURI(aSourceURI, aTargetURI, - nsIScriptSecurityManager::ALLOW_CHROME); + nsresult rv = + secMan->CheckLoadURIWithPrincipal(aSourcePrincipal, aTargetURI, + nsIScriptSecurityManager::ALLOW_CHROME); if (NS_FAILED(rv)) { // failure is normal here; don't warn return rv; } @@ -944,6 +977,7 @@ CSSLoaderImpl::CheckLoadAllowed(nsIURI* aSourceURI, nsresult CSSLoaderImpl::CreateSheet(nsIURI* aURI, nsIContent* aLinkingContent, + nsIPrincipal* aLoaderPrincipal, PRBool aSyncLoad, StyleSheetState& aSheetState, nsICSSStyleSheet** aSheet) @@ -978,28 +1012,50 @@ CSSLoaderImpl::CreateSheet(nsIURI* aURI, #endif if (!sheet) { - // Then complete sheets - mCompleteSheets.Get(aURI, getter_AddRefs(sheet)); + // Then complete sheets. + nsURIAndPrincipalHashKey key(aURI, aLoaderPrincipal); + + mCompleteSheets.Get(&key, getter_AddRefs(sheet)); LOG((" From completed: %p", sheet.get())); // Then loading sheets if (!sheet && !aSyncLoad) { aSheetState = eSheetLoading; SheetLoadData* loadData = nsnull; - mLoadingDatas.Get(aURI, &loadData); + mLoadingDatas.Get(&key, &loadData); if (loadData) { sheet = loadData->mSheet; LOG((" From loading: %p", sheet.get())); + +#ifdef DEBUG + PRBool debugEqual; + NS_ASSERTION((!aLoaderPrincipal && !loadData->mLoaderPrincipal) || + (aLoaderPrincipal && loadData->mLoaderPrincipal && + NS_SUCCEEDED(aLoaderPrincipal-> + Equals(loadData->mLoaderPrincipal, + &debugEqual)) && debugEqual), + "Principals should be the same"); +#endif } // Then alternate sheets if (!sheet) { aSheetState = eSheetPending; SheetLoadData* loadData = nsnull; - mPendingDatas.Get(aURI, &loadData); + mPendingDatas.Get(&key, &loadData); if (loadData) { sheet = loadData->mSheet; LOG((" From pending: %p", sheet.get())); + +#ifdef DEBUG + PRBool debugEqual; + NS_ASSERTION((!aLoaderPrincipal && !loadData->mLoaderPrincipal) || + (aLoaderPrincipal && loadData->mLoaderPrincipal && + NS_SUCCEEDED(aLoaderPrincipal-> + Equals(loadData->mLoaderPrincipal, + &debugEqual)) && debugEqual), + "Principals should be the same"); +#endif } } } @@ -1243,13 +1299,30 @@ CSSLoaderImpl::LoadSheet(SheetLoadData* aLoadData, StyleSheetState aSheetState) // Just load it nsCOMPtr stream; - rv = NS_OpenURI(getter_AddRefs(stream), aLoadData->mURI); + nsCOMPtr channel; + rv = NS_OpenURI(getter_AddRefs(stream), aLoadData->mURI, nsnull, + nsnull, nsnull, nsIRequest::LOAD_NORMAL, + getter_AddRefs(channel)); if (NS_FAILED(rv)) { LOG_ERROR((" Failed to open URI synchronously")); SheetComplete(aLoadData, rv); return rv; } + NS_ASSERTION(channel, "NS_OpenURI lied?"); + + // Get the principal for this channel + nsCOMPtr principal; + rv = nsContentUtils::GetSecurityManager()-> + GetChannelPrincipal(channel, getter_AddRefs(principal)); + if (NS_FAILED(rv)) { + LOG_ERROR((" Failed to get a principal for the sheet")); + SheetComplete(aLoadData, rv); + return rv; + } + + aLoadData->mSheet->SetPrincipal(principal); + nsCOMPtr converterStream = do_CreateInstance("@mozilla.org/intl/converter-input-stream;1", &rv); @@ -1283,12 +1356,13 @@ CSSLoaderImpl::LoadSheet(SheetLoadData* aLoadData, StyleSheetState aSheetState) SheetLoadData* existingData = nsnull; + nsURIAndPrincipalHashKey key(aLoadData->mURI, aLoadData->mLoaderPrincipal); if (aSheetState == eSheetLoading) { - mLoadingDatas.Get(aLoadData->mURI, &existingData); + mLoadingDatas.Get(&key, &existingData); NS_ASSERTION(existingData, "CreateSheet lied about the state"); } else if (aSheetState == eSheetPending){ - mPendingDatas.Get(aLoadData->mURI, &existingData); + mPendingDatas.Get(&key, &existingData); NS_ASSERTION(existingData, "CreateSheet lied about the state"); } @@ -1304,12 +1378,12 @@ CSSLoaderImpl::LoadSheet(SheetLoadData* aLoadData, StyleSheetState aSheetState) #ifdef DEBUG SheetLoadData* removedData; - NS_ASSERTION(mPendingDatas.Get(aLoadData->mURI, &removedData) && + NS_ASSERTION(mPendingDatas.Get(&key, &removedData) && removedData == existingData, "Bad pending table."); #endif - mPendingDatas.Remove(aLoadData->mURI); + mPendingDatas.Remove(&key); LOG((" Forcing load of pending data")); return LoadSheet(existingData, eSheetNeedsParser); @@ -1360,6 +1434,16 @@ CSSLoaderImpl::LoadSheet(SheetLoadData* aLoadData, StyleSheetState aSheetState) // this before opening it, so it's only treated as a hint. channel->SetContentType(NS_LITERAL_CSTRING("text/css")); + if (aLoadData->mLoaderPrincipal) { + PRBool inherit; + rv = NS_URIChainHasFlags(aLoadData->mURI, + nsIProtocolHandler::URI_INHERITS_SECURITY_CONTEXT, + &inherit); + if (NS_SUCCEEDED(rv) && inherit) { + channel->SetOwner(aLoadData->mLoaderPrincipal); + } + } + // We don't have to hold on to the stream loader. The ownership // model is: Necko owns the stream loader, which owns the load data, // which owns us @@ -1380,7 +1464,7 @@ CSSLoaderImpl::LoadSheet(SheetLoadData* aLoadData, StyleSheetState aSheetState) return rv; } - if (!mLoadingDatas.Put(aLoadData->mURI, aLoadData)) { + if (!mLoadingDatas.Put(&key, aLoadData)) { LOG_ERROR((" Failed to put data in loading table")); aLoadData->mIsCancelled = PR_TRUE; channel->Cancel(NS_ERROR_OUT_OF_MEMORY); @@ -1500,14 +1584,16 @@ CSSLoaderImpl::DoSheetComplete(SheetLoadData* aLoadData, nsresult aStatus, LOG_URI(" Finished loading: '%s'", aLoadData->mURI); // Remove the data from the list of loading datas if (aLoadData->mIsLoading) { + nsURIAndPrincipalHashKey key(aLoadData->mURI, + aLoadData->mLoaderPrincipal); #ifdef DEBUG SheetLoadData *loadingData; - NS_ASSERTION(mLoadingDatas.Get(aLoadData->mURI, &loadingData) && + NS_ASSERTION(mLoadingDatas.Get(&key, &loadingData) && loadingData == aLoadData, "Bad loading table"); #endif - mLoadingDatas.Remove(aLoadData->mURI); + mLoadingDatas.Remove(&key); aLoadData->mIsLoading = PR_FALSE; } } @@ -1559,7 +1645,9 @@ CSSLoaderImpl::DoSheetComplete(SheetLoadData* aLoadData, nsresult aStatus, } else { #endif - mCompleteSheets.Put(aLoadData->mURI, aLoadData->mSheet); + nsURIAndPrincipalHashKey key(aLoadData->mURI, + aLoadData->mLoaderPrincipal); + mCompleteSheets.Put(&key, aLoadData->mSheet); #ifdef MOZ_XUL } #endif @@ -1594,9 +1682,12 @@ CSSLoaderImpl::LoadInlineStyle(nsIContent* aElement, nsCOMPtr owningElement(do_QueryInterface(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(). StyleSheetState state; nsCOMPtr sheet; - nsresult rv = CreateSheet(nsnull, aElement, PR_FALSE, state, + nsresult rv = CreateSheet(nsnull, aElement, nsnull, PR_FALSE, state, getter_AddRefs(sheet)); NS_ENSURE_SUCCESS(rv, rv); NS_ASSERTION(state == eSheetNeedsParser, @@ -1613,13 +1704,16 @@ CSSLoaderImpl::LoadInlineStyle(nsIContent* aElement, SheetLoadData* data = new SheetLoadData(this, aTitle, nsnull, sheet, owningElement, *aIsAlternate, - aObserver); + aObserver, nsnull); if (!data) { sheet->SetComplete(); return NS_ERROR_OUT_OF_MEMORY; } + // We never actually load this, so just set its principal directly + sheet->SetPrincipal(aElement->NodePrincipal()); + NS_ADDREF(data); data->mLineNumber = aLineNumber; // Parse completion releases the load data @@ -1662,18 +1756,21 @@ CSSLoaderImpl::LoadStyleLink(nsIContent* aElement, nsIURI *docURI = mDocument->GetDocumentURI(); if (!docURI) return NS_ERROR_FAILURE; + nsIPrincipal* principal = + aElement ? aElement->NodePrincipal() : mDocument->NodePrincipal(); + nsISupports* context = aElement; if (!context) { context = mDocument; } - nsresult rv = CheckLoadAllowed(docURI, aURL, context); + nsresult rv = CheckLoadAllowed(docURI, principal, aURL, context); if (NS_FAILED(rv)) return rv; LOG((" Passed load check")); StyleSheetState state; nsCOMPtr sheet; - rv = CreateSheet(aURL, aElement, PR_FALSE, state, + rv = CreateSheet(aURL, aElement, principal, PR_FALSE, state, getter_AddRefs(sheet)); NS_ENSURE_SUCCESS(rv, rv); @@ -1702,7 +1799,7 @@ CSSLoaderImpl::LoadStyleLink(nsIContent* aElement, // Now we need to actually load it SheetLoadData* data = new SheetLoadData(this, aTitle, aURL, sheet, owningElement, *aIsAlternate, - aObserver); + aObserver, principal); if (!data) { sheet->SetComplete(); return NS_ERROR_OUT_OF_MEMORY; @@ -1714,7 +1811,8 @@ CSSLoaderImpl::LoadStyleLink(nsIContent* aElement, if (aURL && state == eSheetNeedsParser && mLoadingDatas.Count() != 0 && *aIsAlternate) { LOG((" Deferring alternate sheet load")); - if (!mPendingDatas.Put(aURL, data)) { + nsURIAndPrincipalHashKey key(data->mURI, data->mLoaderPrincipal); + if (!mPendingDatas.Put(&key, data)) { return NS_ERROR_OUT_OF_MEMORY; } @@ -1738,6 +1836,7 @@ CSSLoaderImpl::LoadChildSheet(nsICSSStyleSheet* aParentSheet, { LOG(("CSSLoaderImpl::LoadChildSheet")); NS_PRECONDITION(aURL, "Must have a URI to load"); + NS_PRECONDITION(aParentSheet, "Must have a parent sheet"); if (!mEnabled) { LOG_WARN((" Not enabled")); @@ -1775,8 +1874,9 @@ CSSLoaderImpl::LoadChildSheet(nsICSSStyleSheet* aParentSheet, if (!context) { context = mDocument; } - - rv = CheckLoadAllowed(sheetURI, aURL, context); + + nsIPrincipal* principal = aParentSheet->Principal(); + rv = CheckLoadAllowed(sheetURI, principal, aURL, context); if (NS_FAILED(rv)) return rv; LOG((" Passed load check")); @@ -1815,7 +1915,7 @@ CSSLoaderImpl::LoadChildSheet(nsICSSStyleSheet* aParentSheet, // loop) do so nsCOMPtr sheet; StyleSheetState state; - rv = CreateSheet(aURL, nsnull, + rv = CreateSheet(aURL, nsnull, principal, parentData ? parentData->mSyncLoad : PR_FALSE, state, getter_AddRefs(sheet)); NS_ENSURE_SUCCESS(rv, rv); @@ -1837,7 +1937,7 @@ CSSLoaderImpl::LoadChildSheet(nsICSSStyleSheet* aParentSheet, SheetLoadData* data = new SheetLoadData(this, aURL, sheet, parentData, - observer); + observer, principal); if (!data) { sheet->SetComplete(); @@ -1907,7 +2007,7 @@ CSSLoaderImpl::InternalLoadNonDocumentSheet(nsIURI* aURL, nsCOMPtr sheet; PRBool syncLoad = (aObserver == nsnull); - nsresult rv = CreateSheet(aURL, nsnull, syncLoad, state, + nsresult rv = CreateSheet(aURL, nsnull, nsnull, syncLoad, state, getter_AddRefs(sheet)); NS_ENSURE_SUCCESS(rv, rv); @@ -1964,7 +2064,8 @@ CSSLoaderImpl::PostLoadEvent(nsIURI* aURI, aSheet, nsnull, // owning element doesn't matter here aWasAlternate, - aObserver); + aObserver, + nsnull); NS_ENSURE_TRUE(evt, NS_ERROR_OUT_OF_MEMORY); if (!mPostedEvents.AppendElement(evt)) { @@ -2029,7 +2130,9 @@ nsresult NS_NewCSSLoader(nsICSSLoader** aLoader) } PR_STATIC_CALLBACK(PLDHashOperator) -StopLoadingSheetCallback(nsIURI* aKey, SheetLoadData*& aData, void* aClosure) +StopLoadingSheetCallback(nsURIAndPrincipalHashKey* aKey, + SheetLoadData*& aData, + void* aClosure) { NS_PRECONDITION(aData, "Must have a data!"); NS_PRECONDITION(aClosure, "Must have a loader"); @@ -2046,12 +2149,14 @@ StopLoadingSheetCallback(nsIURI* aKey, SheetLoadData*& aData, void* aClosure) NS_IMETHODIMP CSSLoaderImpl::Stop() { - if (mLoadingDatas.IsInitialized() && mLoadingDatas.Count() > 0) { - mLoadingDatas.Enumerate(StopLoadingSheetCallback, this); - } + // Do the pending datas first, since finishing up all the loading + // datas will try to start pending loads. if (mPendingDatas.IsInitialized() && mPendingDatas.Count() > 0) { mPendingDatas.Enumerate(StopLoadingSheetCallback, this); } + if (mLoadingDatas.IsInitialized() && mLoadingDatas.Count() > 0) { + mLoadingDatas.Enumerate(StopLoadingSheetCallback, this); + } for (PRUint32 i = 0; i < mPostedEvents.Length(); ++i) { SheetLoadData* data = mPostedEvents[i]; data->mIsCancelled = PR_TRUE; @@ -2063,44 +2168,56 @@ CSSLoaderImpl::Stop() return NS_OK; } +PR_STATIC_CALLBACK(PLDHashOperator) +StopLoadingSheetByURICallback(nsURIAndPrincipalHashKey* aKey, + SheetLoadData*& aData, + void* aClosure) +{ + NS_PRECONDITION(aData, "Must have a data!"); + NS_PRECONDITION(aClosure, "Must have a loader"); + + PRBool equal; + if (NS_SUCCEEDED(aData->mURI->Equals(NS_STATIC_CAST(nsIURI*, aClosure), + &equal)) && + equal) { + aData->mIsLoading = PR_FALSE; // we will handle the removal right here + aData->mIsCancelled = PR_TRUE; + + aData->mLoader->SheetComplete(aData, NS_BINDING_ABORTED); + + return PL_DHASH_REMOVE; + } + + return PL_DHASH_NEXT; +} + NS_IMETHODIMP CSSLoaderImpl::StopLoadingSheet(nsIURI* aURL) { NS_ENSURE_TRUE(aURL, NS_ERROR_NULL_POINTER); - SheetLoadData* loadData = nsnull; - if (mLoadingDatas.IsInitialized()) { - mLoadingDatas.Get(aURL, &loadData); + // Do the pending datas first, since finishing up all the loading + // datas will try to start pending loads. + if (mPendingDatas.IsInitialized() && mPendingDatas.Count() > 0) { + mPendingDatas.Enumerate(StopLoadingSheetByURICallback, aURL); } - if (!loadData && mPendingDatas.IsInitialized()) { - mPendingDatas.Get(aURL, &loadData); - if (loadData) { - // have to remove from mPendingDatas ourselves, since - // SheetComplete won't do that. - mPendingDatas.Remove(aURL); - } - } - - if (!loadData) { - for (PRUint32 i = 0; i < mPostedEvents.Length(); ++i) { - SheetLoadData* curData = mPostedEvents[i]; - PRBool equal; - if (curData->mURI && NS_SUCCEEDED(curData->mURI->Equals(aURL, &equal)) && - equal) { - loadData = curData; - // SheetComplete() calls Release(), so give it an extra ref. - NS_ADDREF(curData); - mPostedEvents.RemoveElementAt(i); - break; - } + if (mLoadingDatas.IsInitialized() && mLoadingDatas.Count() > 0) { + mLoadingDatas.Enumerate(StopLoadingSheetByURICallback, aURL); + } + + for (PRUint32 i = 0; i < mPostedEvents.Length(); ++i) { + SheetLoadData* curData = mPostedEvents[i-1]; + PRBool equal; + if (curData->mURI && NS_SUCCEEDED(curData->mURI->Equals(aURL, &equal)) && + equal) { + curData->mIsCancelled = PR_TRUE; + // SheetComplete() calls Release(), so give it an extra ref. + NS_ADDREF(curData); + SheetComplete(curData, NS_BINDING_ABORTED); } } + mPostedEvents.Clear(); - if (loadData) { - loadData->mIsCancelled = PR_TRUE; - SheetComplete(loadData, NS_BINDING_ABORTED); - } - return NS_OK; } diff --git a/mozilla/layout/style/nsCSSLoader.h b/mozilla/layout/style/nsCSSLoader.h index 9a23c99c196..5ba23d790e2 100644 --- a/mozilla/layout/style/nsCSSLoader.h +++ b/mozilla/layout/style/nsCSSLoader.h @@ -71,6 +71,7 @@ class nsMediaList; #include "nsDataHashtable.h" #include "nsAutoPtr.h" #include "nsTArray.h" +#include "nsIPrincipal.h" /** * OVERALL ARCHITECTURE @@ -116,14 +117,16 @@ public: nsICSSStyleSheet* aSheet, nsIStyleSheetLinkingElement* aOwningElement, PRBool aIsAlternate, - nsICSSLoaderObserver* aObserver); + nsICSSLoaderObserver* aObserver, + nsIPrincipal* aLoaderPrincipal); // Data for loading a sheet linked from an @import rule SheetLoadData(CSSLoaderImpl* aLoader, nsIURI* aURI, nsICSSStyleSheet* aSheet, SheetLoadData* aParentData, - nsICSSLoaderObserver* aObserver); + nsICSSLoaderObserver* aObserver, + nsIPrincipal* aLoaderPrincipal); // Data for loading a non-document sheet SheetLoadData(CSSLoaderImpl* aLoader, @@ -209,8 +212,68 @@ public: // The observer that wishes to be notified of load completion nsCOMPtr mObserver; + + // The principal that identifies who started loading us. + nsCOMPtr mLoaderPrincipal; }; +class nsURIAndPrincipalHashKey : public nsURIHashKey +{ +public: + typedef nsURIAndPrincipalHashKey* KeyType; + typedef const nsURIAndPrincipalHashKey* KeyTypePointer; + + nsURIAndPrincipalHashKey(const nsURIAndPrincipalHashKey* aKey) + : nsURIHashKey(aKey->mKey), mPrincipal(aKey->mPrincipal) + { + MOZ_COUNT_CTOR(nsURIAndPrincipalHashKey); + } + nsURIAndPrincipalHashKey(nsIURI* aURI, nsIPrincipal* aPrincipal) + : nsURIHashKey(aURI), mPrincipal(aPrincipal) + { + MOZ_COUNT_CTOR(nsURIAndPrincipalHashKey); + } + nsURIAndPrincipalHashKey(const nsURIAndPrincipalHashKey& toCopy) + : nsURIHashKey(toCopy), mPrincipal(toCopy.mPrincipal) + { + MOZ_COUNT_CTOR(nsURIAndPrincipalHashKey); + } + ~nsURIAndPrincipalHashKey() + { + MOZ_COUNT_DTOR(nsURIAndPrincipalHashKey); + } + + nsURIAndPrincipalHashKey* GetKey() const { + return NS_CONST_CAST(nsURIAndPrincipalHashKey*, this); + } + const nsURIAndPrincipalHashKey* GetKeyPointer() const { return this; } + + PRBool KeyEquals(const nsURIAndPrincipalHashKey* aKey) const { + if (!nsURIHashKey::KeyEquals(aKey->mKey)) { + return PR_FALSE; + } + + if (!mPrincipal != !aKey->mPrincipal) { + // One or the other has a principal, but not both... not equal + return PR_FALSE; + } + + PRBool eq; + return !mPrincipal || + NS_SUCCEEDED(mPrincipal->Equals(aKey->mPrincipal, &eq)) && eq; + } + + static const nsURIAndPrincipalHashKey* + KeyToPointer(nsURIAndPrincipalHashKey* aKey) { return aKey; } + static PLDHashNumber HashKey(const nsURIAndPrincipalHashKey* aKey) { + return nsURIHashKey::HashKey(aKey->mKey); + } + + enum { ALLOW_MEMMOVE = PR_TRUE }; + +protected: + nsCOMPtr mPrincipal; +}; /*********************************************************************** * Enum that describes the state of the sheet returned by CreateSheet. * @@ -305,14 +368,17 @@ public: private: nsresult CheckLoadAllowed(nsIURI* aSourceURI, + nsIPrincipal* aSourcePrincipal, nsIURI* aTargetURI, nsISupports* aContext); // For inline style, the aURI param is null, but the aLinkingContent - // must be non-null then. + // must be non-null then. The loader principal must never be null + // if aURI is not null. nsresult CreateSheet(nsIURI* aURI, nsIContent* aLinkingContent, + nsIPrincipal* aLoaderPrincipal, PRBool aSyncLoad, StyleSheetState& aSheetState, nsICSSStyleSheet** aSheet); @@ -401,9 +467,12 @@ private: nsCompatibility mCompatMode; nsString mPreferredSheet; // title of preferred sheet - nsInterfaceHashtable mCompleteSheets; - nsDataHashtable mLoadingDatas; // weak refs - nsDataHashtable mPendingDatas; // weak refs + nsInterfaceHashtable mCompleteSheets; + nsDataHashtable mLoadingDatas; // weak refs + nsDataHashtable mPendingDatas; // weak refs // We're not likely to have many levels of @import... But likely to have // some. Allocate some storage, what the hell. diff --git a/mozilla/layout/style/nsCSSStyleSheet.cpp b/mozilla/layout/style/nsCSSStyleSheet.cpp index 3c332cd10c5..72e693e79e0 100644 --- a/mozilla/layout/style/nsCSSStyleSheet.cpp +++ b/mozilla/layout/style/nsCSSStyleSheet.cpp @@ -496,9 +496,14 @@ static PRBool SetStyleSheetReference(nsICSSRule* aRule, void* aSheet) nsCSSStyleSheetInner::nsCSSStyleSheetInner(nsICSSStyleSheet* aParentSheet) : mSheets(), mComplete(PR_FALSE) +#ifdef DEBUG + , mPrincipalSet(PR_FALSE) +#endif { MOZ_COUNT_CTOR(nsCSSStyleSheetInner); mSheets.AppendElement(aParentSheet); + + mPrincipal = do_CreateInstance("@mozilla.org/nullprincipal;1"); } static PRBool @@ -514,11 +519,15 @@ CloneRuleInto(nsICSSRule* aRule, void* aArray) } nsCSSStyleSheetInner::nsCSSStyleSheetInner(nsCSSStyleSheetInner& aCopy, - nsICSSStyleSheet* aParentSheet) + nsICSSStyleSheet* aParentSheet) : mSheets(), mSheetURI(aCopy.mSheetURI), mBaseURI(aCopy.mBaseURI), + mPrincipal(aCopy.mPrincipal), mComplete(aCopy.mComplete) +#ifdef DEBUG + , mPrincipalSet(aCopy.mPrincipalSet) +#endif { MOZ_COUNT_CTOR(nsCSSStyleSheetInner); mSheets.AppendElement(aParentSheet); @@ -629,10 +638,10 @@ nsCSSStyleSheet::nsCSSStyleSheet() } nsCSSStyleSheet::nsCSSStyleSheet(const nsCSSStyleSheet& aCopy, - nsICSSStyleSheet* aParentToUse, - nsICSSImportRule* aOwnerRuleToUse, - nsIDocument* aDocumentToUse, - nsIDOMNode* aOwningNodeToUse) + nsICSSStyleSheet* aParentToUse, + nsICSSImportRule* aOwnerRuleToUse, + nsIDocument* aDocumentToUse, + nsIDOMNode* aOwningNodeToUse) : nsICSSStyleSheet(), mRefCnt(0), mTitle(aCopy.mTitle), @@ -766,10 +775,6 @@ nsCSSStyleSheet::SetURIs(nsIURI* aSheetURI, nsIURI* aBaseURI) { NS_PRECONDITION(aSheetURI && aBaseURI, "null ptr"); - if (! mInner) { - return NS_ERROR_OUT_OF_MEMORY; - } - NS_ASSERTION(mInner->mOrderedRules.Count() == 0 && !mInner->mComplete, "Can't call SetURL on sheets that are complete or have rules"); @@ -778,17 +783,36 @@ nsCSSStyleSheet::SetURIs(nsIURI* aSheetURI, nsIURI* aBaseURI) return NS_OK; } +void +nsCSSStyleSheet::SetPrincipal(nsIPrincipal* aPrincipal) +{ + NS_PRECONDITION(!mInner->mPrincipalSet, + "Should have an inner whose principal has not yet been set"); + if (aPrincipal) { + mInner->mPrincipal = aPrincipal; +#ifdef DEBUG + mInner->mPrincipalSet = PR_TRUE; +#endif + } +} + +nsIPrincipal* +nsCSSStyleSheet::Principal() const +{ + return mInner->mPrincipal; +} + NS_IMETHODIMP nsCSSStyleSheet::GetSheetURI(nsIURI** aSheetURI) const { - NS_IF_ADDREF(*aSheetURI = (mInner ? mInner->mSheetURI.get() : nsnull)); + NS_IF_ADDREF(*aSheetURI = mInner->mSheetURI.get()); return NS_OK; } NS_IMETHODIMP nsCSSStyleSheet::GetBaseURI(nsIURI** aBaseURI) const { - NS_IF_ADDREF(*aBaseURI = (mInner ? mInner->mBaseURI.get() : nsnull)); + NS_IF_ADDREF(*aBaseURI = mInner->mBaseURI.get()); return NS_OK; } @@ -834,7 +858,7 @@ nsCSSStyleSheet::HasRules() const NS_IMETHODIMP nsCSSStyleSheet::GetApplicable(PRBool& aApplicable) const { - aApplicable = !mDisabled && mInner && mInner->mComplete; + aApplicable = !mDisabled && mInner->mComplete; return NS_OK; } @@ -845,7 +869,7 @@ nsCSSStyleSheet::SetEnabled(PRBool aEnabled) PRBool oldDisabled = mDisabled; mDisabled = !aEnabled; - if (mDocument && mInner && mInner->mComplete && oldDisabled != mDisabled) { + if (mDocument && mInner->mComplete && oldDisabled != mDisabled) { ClearRuleCascades(); mDocument->SetStyleSheetApplicableState(this, !mDisabled); @@ -857,15 +881,13 @@ nsCSSStyleSheet::SetEnabled(PRBool aEnabled) NS_IMETHODIMP nsCSSStyleSheet::GetComplete(PRBool& aComplete) const { - aComplete = mInner && mInner->mComplete; + aComplete = mInner->mComplete; return NS_OK; } NS_IMETHODIMP nsCSSStyleSheet::SetComplete() { - if (!mInner) - return NS_ERROR_UNEXPECTED; NS_ASSERTION(!mDirty, "Can't set a dirty sheet complete!"); mInner->mComplete = PR_TRUE; if (mDocument && !mDisabled) { @@ -931,7 +953,7 @@ nsCSSStyleSheet::ContainsStyleSheet(nsIURI* aURL, PRBool& aContains, nsIStyleShe { NS_PRECONDITION(nsnull != aURL, "null arg"); - if (!mInner || !mInner->mSheetURI) { + if (!mInner->mSheetURI) { // We're not yet far enough along in our load to know what our URL is (we // may still get redirected and such). Assert (caller should really not be // calling this on us at this stage) and return. @@ -1084,8 +1106,7 @@ NS_IMETHODIMP nsCSSStyleSheet::ReplaceStyleRule(nsICSSRule* aOld, nsICSSRule* aNew) { NS_PRECONDITION(mInner->mOrderedRules.Count() != 0, "can't have old rule"); - NS_PRECONDITION(mInner && mInner->mComplete, - "No replacing in an incomplete sheet!"); + NS_PRECONDITION(mInner->mComplete, "No replacing in an incomplete sheet!"); if (NS_SUCCEEDED(WillDirty())) { PRInt32 index = mInner->mOrderedRules.IndexOf(aOld); @@ -1109,10 +1130,7 @@ nsCSSStyleSheet::ReplaceStyleRule(nsICSSRule* aOld, nsICSSRule* aNew) NS_IMETHODIMP nsCSSStyleSheet::StyleRuleCount(PRInt32& aCount) const { - aCount = 0; - if (mInner) { - aCount = mInner->mOrderedRules.Count(); - } + aCount = mInner->mOrderedRules.Count(); return NS_OK; } @@ -1121,27 +1139,19 @@ nsCSSStyleSheet::GetStyleRuleAt(PRInt32 aIndex, nsICSSRule*& aRule) const { // Important: If this function is ever made scriptable, we must add // a security check here. See GetCSSRules below for an example. - nsresult result = NS_ERROR_ILLEGAL_VALUE; + aRule = mInner->mOrderedRules.SafeObjectAt(aIndex); + if (aRule) { + NS_ADDREF(aRule); + return NS_OK; + } - if (mInner) { - NS_IF_ADDREF(aRule = mInner->mOrderedRules.SafeObjectAt(aIndex)); - if (nsnull != aRule) { - result = NS_OK; - } - } - else { - aRule = nsnull; - } - return result; + return NS_ERROR_ILLEGAL_VALUE; } nsXMLNameSpaceMap* nsCSSStyleSheet::GetNameSpaceMap() const { - if (mInner) - return mInner->mNameSpaceMap; - - return nsnull; + return mInner->mNameSpaceMap; } NS_IMETHODIMP @@ -1186,9 +1196,6 @@ nsCSSStyleSheet::GetStyleSheetAt(PRInt32 aIndex, nsICSSStyleSheet*& aSheet) cons nsresult nsCSSStyleSheet::EnsureUniqueInner() { - if (! mInner) { - return NS_ERROR_NOT_INITIALIZED; - } if (1 < mInner->mSheets.Count()) { nsCSSStyleSheetInner* clone = mInner->CloneFor(this); if (clone) { @@ -1249,11 +1256,6 @@ void nsCSSStyleSheet::List(FILE* out, PRInt32 aIndent) const // Indent for (index = aIndent; --index >= 0; ) fputs(" ", out); - if (! mInner) { - fputs("CSS Style Sheet - without inner data storage - ERROR\n", out); - return; - } - fputs("CSS Style Sheet: ", out); nsCAutoString urlSpec; nsresult rv = mInner->mSheetURI->GetSpec(urlSpec); @@ -1304,7 +1306,7 @@ nsCSSStyleSheet::ClearRuleCascades() nsresult nsCSSStyleSheet::WillDirty() { - if (mInner && !mInner->mComplete) { + if (!mInner->mComplete) { // Do nothing return NS_OK; } @@ -1388,7 +1390,7 @@ nsCSSStyleSheet::GetHref(nsAString& aHref) nsCAutoString str; // XXXldb The DOM spec says that this should be null for inline style sheets. - if (mInner && mInner->mSheetURI) { + if (mInner->mSheetURI) { mInner->mSheetURI->GetSpec(str); } @@ -1450,28 +1452,28 @@ nsCSSStyleSheet::GetCssRules(nsIDOMCSSRuleList** aCssRules) return NS_ERROR_DOM_INVALID_ACCESS_ERR; } - //-- Security check: Only scripts from the same origin as the - // style sheet can access rule collections + //-- Security check: Only scripts whose principal subsumes that of the + // style sheet can access rule collections. - // Get JSContext from stack - nsCOMPtr stack = - do_GetService("@mozilla.org/js/xpc/ContextStack;1"); - NS_ENSURE_TRUE(stack, NS_ERROR_FAILURE); - - JSContext *cx = nsnull; - nsresult rv = NS_OK; - - rv = stack->Peek(&cx); - NS_ENSURE_SUCCESS(rv, rv); - if (!cx) - return NS_ERROR_FAILURE; - - // Get the security manager and do the same-origin check + // Get the security manager and do the subsumes check nsIScriptSecurityManager *securityManager = nsContentUtils::GetSecurityManager(); - rv = securityManager->CheckSameOrigin(cx, mInner->mSheetURI); - if (NS_FAILED(rv)) { - return rv; + + nsCOMPtr subjectPrincipal; + securityManager->GetSubjectPrincipal(getter_AddRefs(subjectPrincipal)); + + nsresult rv = NS_OK; + if (subjectPrincipal) { + PRBool subsumes; + rv = subjectPrincipal->Subsumes(mInner->mPrincipal, &subsumes); + if (NS_SUCCEEDED(rv) && !subsumes && + !nsContentUtils::IsCallerTrustedForRead()) { + rv = NS_ERROR_DOM_SECURITY_ERR; + } + + if (NS_FAILED(rv)) { + return rv; + } } // OK, security check passed, so get the rule collection @@ -1494,7 +1496,6 @@ nsCSSStyleSheet::InsertRule(const nsAString& aRule, PRUint32 aIndex, PRUint32* aReturn) { - NS_ENSURE_TRUE(mInner, NS_ERROR_FAILURE); // No doing this if the sheet is not complete! PRBool complete; GetComplete(complete); @@ -1672,28 +1673,26 @@ nsCSSStyleSheet::DeleteRule(PRUint32 aIndex) } // XXX TBI: handle @rule types - if (mInner) { - mozAutoDocUpdate updateBatch(mDocument, UPDATE_STYLE, PR_TRUE); + mozAutoDocUpdate updateBatch(mDocument, UPDATE_STYLE, PR_TRUE); - result = WillDirty(); + result = WillDirty(); - if (NS_SUCCEEDED(result)) { - if (aIndex >= PRUint32(mInner->mOrderedRules.Count())) - return NS_ERROR_DOM_INDEX_SIZE_ERR; + if (NS_SUCCEEDED(result)) { + if (aIndex >= PRUint32(mInner->mOrderedRules.Count())) + return NS_ERROR_DOM_INDEX_SIZE_ERR; - NS_ASSERTION(PRUint32(mInner->mOrderedRules.Count()) <= PR_INT32_MAX, - "Too many style rules!"); + NS_ASSERTION(PRUint32(mInner->mOrderedRules.Count()) <= PR_INT32_MAX, + "Too many style rules!"); - // Hold a strong ref to the rule so it doesn't die when we RemoveObjectAt - nsCOMPtr rule = mInner->mOrderedRules.ObjectAt(aIndex); - if (rule) { - mInner->mOrderedRules.RemoveObjectAt(aIndex); - rule->SetStyleSheet(nsnull); - DidDirty(); + // Hold a strong ref to the rule so it doesn't die when we RemoveObjectAt + nsCOMPtr rule = mInner->mOrderedRules.ObjectAt(aIndex); + if (rule) { + mInner->mOrderedRules.RemoveObjectAt(aIndex); + rule->SetStyleSheet(nsnull); + DidDirty(); - if (mDocument) { - mDocument->StyleRuleRemoved(this, rule); - } + if (mDocument) { + mDocument->StyleRuleRemoved(this, rule); } } } @@ -1705,8 +1704,7 @@ NS_IMETHODIMP nsCSSStyleSheet::DeleteRuleFromGroup(nsICSSGroupRule* aGroup, PRUint32 aIndex) { NS_ENSURE_ARG_POINTER(aGroup); - NS_ASSERTION(mInner && mInner->mComplete, - "No deleting from an incomplete sheet!"); + NS_ASSERTION(mInner->mComplete, "No deleting from an incomplete sheet!"); nsresult result; nsCOMPtr rule; result = aGroup->GetStyleRuleAt(aIndex, *getter_AddRefs(rule)); @@ -1745,8 +1743,7 @@ nsCSSStyleSheet::InsertRuleIntoGroup(const nsAString & aRule, PRUint32* _retval) { nsresult result; - NS_ASSERTION(mInner && mInner->mComplete, - "No inserting into an incomplete sheet!"); + NS_ASSERTION(mInner->mComplete, "No inserting into an incomplete sheet!"); // check that the group actually belongs to this sheet! nsCOMPtr groupSheet; aGroup->GetStyleSheet(*getter_AddRefs(groupSheet)); @@ -1831,8 +1828,7 @@ nsCSSStyleSheet::ReplaceRuleInGroup(nsICSSGroupRule* aGroup, nsICSSRule* aOld, nsICSSRule* aNew) { nsresult result; - NS_PRECONDITION(mInner && mInner->mComplete, - "No replacing in an incomplete sheet!"); + NS_PRECONDITION(mInner->mComplete, "No replacing in an incomplete sheet!"); #ifdef DEBUG { nsCOMPtr groupSheet; @@ -1883,13 +1879,20 @@ nsCSSStyleSheet::StyleSheetLoaded(nsICSSStyleSheet* aSheet, nsresult NS_NewCSSStyleSheet(nsICSSStyleSheet** aInstancePtrResult) { + *aInstancePtrResult = nsnull; nsCSSStyleSheet *it = new nsCSSStyleSheet(); - if (nsnull == it) { + if (!it) { return NS_ERROR_OUT_OF_MEMORY; } NS_ADDREF(it); + + if (!it->mInner || !it->mInner->mPrincipal) { + NS_RELEASE(it); + return NS_ERROR_OUT_OF_MEMORY; + } + *aInstancePtrResult = it; return NS_OK; } diff --git a/mozilla/layout/style/nsCSSStyleSheet.h b/mozilla/layout/style/nsCSSStyleSheet.h index 6cfcc9eaa06..d7cf9c34b91 100644 --- a/mozilla/layout/style/nsCSSStyleSheet.h +++ b/mozilla/layout/style/nsCSSStyleSheet.h @@ -75,9 +75,14 @@ public: nsAutoVoidArray mSheets; nsCOMPtr mSheetURI; // for error reports, etc. nsCOMPtr mBaseURI; // for resolving relative URIs + nsCOMPtr mPrincipal; nsCOMArray mOrderedRules; nsAutoPtr mNameSpaceMap; - PRPackedBool mComplete; + PRBool mComplete; + +#ifdef DEBUG + PRBool mPrincipalSet; +#endif }; @@ -132,6 +137,8 @@ public: NS_IMETHOD StyleSheetCount(PRInt32& aCount) const; NS_IMETHOD GetStyleSheetAt(PRInt32 aIndex, nsICSSStyleSheet*& aSheet) const; NS_IMETHOD SetURIs(nsIURI* aSheetURI, nsIURI* aBaseURI); + virtual NS_HIDDEN_(void) SetPrincipal(nsIPrincipal* aPrincipal); + virtual NS_HIDDEN_(nsIPrincipal*) Principal() const; NS_IMETHOD SetTitle(const nsAString& aTitle); NS_IMETHOD SetMedia(nsMediaList* aMedia); NS_IMETHOD SetOwningNode(nsIDOMNode* aOwningNode); @@ -200,6 +207,7 @@ protected: friend class nsMediaList; friend PRBool CascadeSheetRulesInto(nsICSSStyleSheet* aSheet, void* aData); + friend nsresult NS_NewCSSStyleSheet(nsICSSStyleSheet** aInstancePtrResult); }; #endif /* !defined(nsCSSStyleSheet_h_) */ diff --git a/mozilla/layout/style/nsICSSStyleSheet.h b/mozilla/layout/style/nsICSSStyleSheet.h index 0c68cbbf143..77df3fa9ed9 100644 --- a/mozilla/layout/style/nsICSSStyleSheet.h +++ b/mozilla/layout/style/nsICSSStyleSheet.h @@ -50,11 +50,13 @@ class nsCSSRuleProcessor; class nsMediaList; class nsICSSGroupRule; class nsICSSImportRule; +class nsIPrincipal; // IID for the nsICSSStyleSheet interface -// 446df065-af5e-46b8-b32f-289bf5906876 +// 36541c18-e735-48ef-8622-3a481275b757 #define NS_ICSS_STYLE_SHEET_IID \ -{0x446df065, 0xaf5e, 0x46b8, {0xb3, 0x2f, 0x28, 0x9b, 0xf5, 0x90, 0x68, 0x76}} +{ 0x36541c18, 0xe735, 0x48ef, \ + { 0x86, 0x22, 0x3a, 0x48, 0x12, 0x75, 0xb7, 0x57 } } class nsICSSStyleSheet : public nsIStyleSheet { public: @@ -86,6 +88,17 @@ public: * has no rules in it */ NS_IMETHOD SetURIs(nsIURI* aSheetURI, nsIURI* aBaseURI) = 0; + + /** + * SetPrincipal should be called on all sheets before parsing into them. + * This can only be called once with a non-null principal. Calling this with + * a null pointer is allowed and is treated as a no-op. + */ + virtual NS_HIDDEN_(void) SetPrincipal(nsIPrincipal* aPrincipal) = 0; + + // Principal() never returns a null pointer. + virtual NS_HIDDEN_(nsIPrincipal*) Principal() const = 0; + NS_IMETHOD SetTitle(const nsAString& aTitle) = 0; NS_IMETHOD SetMedia(nsMediaList* aMedia) = 0; NS_IMETHOD SetOwningNode(nsIDOMNode* aOwningNode) = 0; diff --git a/mozilla/layout/style/test/Makefile.in b/mozilla/layout/style/test/Makefile.in index c660335beb8..64171cfb8d8 100644 --- a/mozilla/layout/style/test/Makefile.in +++ b/mozilla/layout/style/test/Makefile.in @@ -66,7 +66,8 @@ css_properties.js: host_ListCSSProperties$(HOST_BIN_SUFFIX) css_properties_like_ ./host_ListCSSProperties$(HOST_BIN_SUFFIX) > $@ cat $(srcdir)/css_properties_like_longhand.js >> $@ -_TEST_FILES = test_bug302186.html \ +_TEST_FILES = test_bug221428.html \ + test_bug302186.html \ test_bug319381.html \ test_bug365932.html \ test_bug372770.html \ diff --git a/mozilla/layout/style/test/test_bug221428.html b/mozilla/layout/style/test/test_bug221428.html new file mode 100644 index 00000000000..b48d276996f --- /dev/null +++ b/mozilla/layout/style/test/test_bug221428.html @@ -0,0 +1,69 @@ + + + + + Test for Bug 221428 + + + + + + + + + +Mozilla Bug 221428 +

+ +
+
+
+ + + diff --git a/mozilla/netwerk/base/public/nsURIHashKey.h b/mozilla/netwerk/base/public/nsURIHashKey.h index ade618662d7..cd4984b2101 100644 --- a/mozilla/netwerk/base/public/nsURIHashKey.h +++ b/mozilla/netwerk/base/public/nsURIHashKey.h @@ -77,7 +77,7 @@ public: enum { ALLOW_MEMMOVE = PR_TRUE }; -private: +protected: nsCOMPtr mKey; };