зеркало из https://github.com/mozilla/gecko-dev.git
Pass through loader principal and URI to LoadSheet(). Bug 387317, r+sr=peterv
This commit is contained in:
Родитель
aeb26bffdf
Коммит
0a0534efd5
|
@ -139,6 +139,7 @@ nsXBLResourceLoader::LoadResources(PRBool* aResult)
|
|||
// Kick off the load of the stylesheet.
|
||||
|
||||
// Always load chrome synchronously
|
||||
// XXXbz should that still do a content policy check?
|
||||
PRBool chrome;
|
||||
nsresult rv;
|
||||
if (NS_SUCCEEDED(url->SchemeIs("chrome", &chrome)) && chrome)
|
||||
|
@ -154,7 +155,7 @@ nsXBLResourceLoader::LoadResources(PRBool* aResult)
|
|||
}
|
||||
else
|
||||
{
|
||||
rv = cssLoader->LoadSheet(url, this);
|
||||
rv = cssLoader->LoadSheet(url, docURL, doc->NodePrincipal(), this);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
++mPendingSheets;
|
||||
}
|
||||
|
|
|
@ -199,8 +199,8 @@ struct BroadcastListener {
|
|||
|
||||
nsXULDocument::nsXULDocument(void)
|
||||
: nsXMLDocument("application/vnd.mozilla.xul+xml"),
|
||||
mResolutionPhase(nsForwardReference::eStart),
|
||||
mState(eState_Master)
|
||||
mState(eState_Master),
|
||||
mResolutionPhase(nsForwardReference::eStart)
|
||||
{
|
||||
|
||||
// NOTE! nsDocument::operator new() zeroes out all members, so don't
|
||||
|
@ -2594,9 +2594,6 @@ nsXULDocument::LoadOverlayInternal(nsIURI* aURI, PRBool aIsDynamic,
|
|||
*aShouldReturn = PR_FALSE;
|
||||
*aFailureFromContent = PR_FALSE;
|
||||
|
||||
nsCOMPtr<nsIScriptSecurityManager> secMan = do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
#ifdef PR_LOGGING
|
||||
if (PR_LOG_TEST(gXULLog, PR_LOG_DEBUG)) {
|
||||
nsCAutoString urlspec;
|
||||
|
@ -2610,6 +2607,9 @@ nsXULDocument::LoadOverlayInternal(nsIURI* aURI, PRBool aIsDynamic,
|
|||
if (aIsDynamic)
|
||||
mResolutionPhase = nsForwardReference::eStart;
|
||||
|
||||
nsIScriptSecurityManager* secMan = nsContentUtils::GetSecurityManager();
|
||||
NS_ENSURE_TRUE(secMan, NS_ERROR_NOT_AVAILABLE);
|
||||
|
||||
// Chrome documents are allowed to load overlays from anywhere.
|
||||
// Also, any document may load a chrome:// overlay.
|
||||
// In all other cases, the overlay is only allowed to load if
|
||||
|
@ -2675,10 +2675,9 @@ nsXULDocument::LoadOverlayInternal(nsIURI* aURI, PRBool aIsDynamic,
|
|||
// Not there. Initiate a load.
|
||||
PR_LOG(gXULLog, PR_LOG_DEBUG, ("xul: overlay was not cached"));
|
||||
|
||||
// No one ever uses overlay principals for anything, so it's OK to give
|
||||
// them the null principal. Too bad this code insists on the sort of
|
||||
// syncloading that can't provide us the right principal from the
|
||||
// channel...
|
||||
// We'll set the right principal on the proto doc when we get
|
||||
// OnStartRequest from the parser, so just pass in a null principal for
|
||||
// now.
|
||||
nsCOMPtr<nsIParser> parser;
|
||||
rv = PrepareToLoadPrototype(aURI, "view", nsnull, getter_AddRefs(parser));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
@ -2695,7 +2694,8 @@ nsXULDocument::LoadOverlayInternal(nsIURI* aURI, PRBool aIsDynamic,
|
|||
// Add an observer to the parser; this'll get called when
|
||||
// Necko fires its On[Start|Stop]Request() notifications,
|
||||
// and will let us recover from a missing overlay.
|
||||
ParserObserver* parserObserver = new ParserObserver(this);
|
||||
ParserObserver* parserObserver =
|
||||
new ParserObserver(this, mCurrentPrototype);
|
||||
if (! parserObserver)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
|
@ -3699,7 +3699,9 @@ nsXULDocument::AddPrototypeSheets()
|
|||
nsCOMPtr<nsIURI> uri = sheets[i];
|
||||
|
||||
nsCOMPtr<nsICSSStyleSheet> incompleteSheet;
|
||||
rv = CSSLoader()->LoadSheet(uri, this, getter_AddRefs(incompleteSheet));
|
||||
rv = CSSLoader()->LoadSheet(uri, mCurrentPrototype->GetURI(),
|
||||
mCurrentPrototype->DocumentPrincipal(),
|
||||
this, getter_AddRefs(incompleteSheet));
|
||||
|
||||
// XXXldb We need to prevent bogus sheets from being held in the
|
||||
// prototype's list, but until then, don't propagate the failure
|
||||
|
@ -4332,15 +4334,14 @@ nsXULDocument::CachedChromeStreamListener::OnDataAvailable(nsIRequest *request,
|
|||
// ParserObserver
|
||||
//
|
||||
|
||||
nsXULDocument::ParserObserver::ParserObserver(nsXULDocument* aDocument)
|
||||
: mDocument(aDocument)
|
||||
nsXULDocument::ParserObserver::ParserObserver(nsXULDocument* aDocument,
|
||||
nsXULPrototypeDocument* aPrototype)
|
||||
: mDocument(aDocument), mPrototype(aPrototype)
|
||||
{
|
||||
NS_ADDREF(mDocument);
|
||||
}
|
||||
|
||||
nsXULDocument::ParserObserver::~ParserObserver()
|
||||
{
|
||||
NS_IF_RELEASE(mDocument);
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsXULDocument::ParserObserver, nsIRequestObserver)
|
||||
|
@ -4349,6 +4350,22 @@ NS_IMETHODIMP
|
|||
nsXULDocument::ParserObserver::OnStartRequest(nsIRequest *request,
|
||||
nsISupports* aContext)
|
||||
{
|
||||
// Guard against buggy channels calling OnStartRequest multiple times.
|
||||
if (mPrototype) {
|
||||
nsCOMPtr<nsIChannel> channel = do_QueryInterface(request);
|
||||
nsIScriptSecurityManager* secMan = nsContentUtils::GetSecurityManager();
|
||||
if (channel && secMan) {
|
||||
nsCOMPtr<nsIPrincipal> principal;
|
||||
secMan->GetChannelPrincipal(channel, getter_AddRefs(principal));
|
||||
|
||||
// Failure there is ok -- it'll just set a (safe) null principal
|
||||
mPrototype->SetDocumentPrincipal(principal);
|
||||
}
|
||||
|
||||
// Make sure to avoid cycles
|
||||
mPrototype = nsnull;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -4377,7 +4394,7 @@ nsXULDocument::ParserObserver::OnStopRequest(nsIRequest *request,
|
|||
// Drop the reference to the document to break cycle between the
|
||||
// document, the parser, the content sink, and the parser
|
||||
// observer.
|
||||
NS_RELEASE(mDocument);
|
||||
mDocument = nsnull;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
|
|
@ -658,11 +658,13 @@ protected:
|
|||
|
||||
class ParserObserver : public nsIRequestObserver {
|
||||
protected:
|
||||
nsXULDocument* mDocument;
|
||||
nsRefPtr<nsXULDocument> mDocument;
|
||||
nsRefPtr<nsXULPrototypeDocument> mPrototype;
|
||||
virtual ~ParserObserver();
|
||||
|
||||
public:
|
||||
ParserObserver(nsXULDocument* aDocument);
|
||||
ParserObserver(nsXULDocument* aDocument,
|
||||
nsXULPrototypeDocument* aPrototype);
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIREQUESTOBSERVER
|
||||
|
|
|
@ -541,6 +541,11 @@ nsXULPrototypeDocument::DocumentPrincipal()
|
|||
return mNodeInfoManager->DocumentPrincipal();
|
||||
}
|
||||
|
||||
void
|
||||
nsXULPrototypeDocument::SetDocumentPrincipal(nsIPrincipal* aPrincipal)
|
||||
{
|
||||
mNodeInfoManager->SetDocumentPrincipal(aPrincipal);
|
||||
}
|
||||
|
||||
nsNodeInfoManager*
|
||||
nsXULPrototypeDocument::GetNodeInfoManager()
|
||||
|
|
|
@ -3552,7 +3552,7 @@ nsHTMLEditor::ReplaceStyleSheet(const nsAString& aURL)
|
|||
rv = NS_NewURI(getter_AddRefs(uaURI), aURL);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = cssLoader->LoadSheet(uaURI, this);
|
||||
rv = cssLoader->LoadSheet(uaURI, nsnull, nsnull, this);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
|
|
|
@ -214,7 +214,8 @@ SheetLoadData::SheetLoadData(CSSLoaderImpl* aLoader,
|
|||
nsICSSStyleSheet* aSheet,
|
||||
PRBool aSyncLoad,
|
||||
PRBool aAllowUnsafeRules,
|
||||
nsICSSLoaderObserver* aObserver)
|
||||
nsICSSLoaderObserver* aObserver,
|
||||
nsIPrincipal* aLoaderPrincipal)
|
||||
: mLoader(aLoader),
|
||||
mURI(aURI),
|
||||
mLineNumber(1),
|
||||
|
@ -231,7 +232,7 @@ SheetLoadData::SheetLoadData(CSSLoaderImpl* aLoader,
|
|||
mAllowUnsafeRules(aAllowUnsafeRules),
|
||||
mOwningElement(nsnull),
|
||||
mObserver(aObserver),
|
||||
mLoaderPrincipal(nsnull)
|
||||
mLoaderPrincipal(aLoaderPrincipal)
|
||||
{
|
||||
|
||||
NS_PRECONDITION(mLoader, "Must have a loader!");
|
||||
|
@ -933,36 +934,42 @@ CSSLoaderImpl::CheckLoadAllowed(nsIURI* aSourceURI,
|
|||
nsISupports* aContext)
|
||||
{
|
||||
LOG(("CSSLoaderImpl::CheckLoadAllowed"));
|
||||
|
||||
nsresult rv;
|
||||
|
||||
// Check with the security manager
|
||||
nsIScriptSecurityManager *secMan = nsContentUtils::GetSecurityManager();
|
||||
nsresult rv =
|
||||
secMan->CheckLoadURIWithPrincipal(aSourcePrincipal, aTargetURI,
|
||||
nsIScriptSecurityManager::ALLOW_CHROME);
|
||||
if (NS_FAILED(rv)) { // failure is normal here; don't warn
|
||||
return rv;
|
||||
if (aSourcePrincipal) {
|
||||
// Check with the security manager
|
||||
nsIScriptSecurityManager *secMan = nsContentUtils::GetSecurityManager();
|
||||
rv =
|
||||
secMan->CheckLoadURIWithPrincipal(aSourcePrincipal, aTargetURI,
|
||||
nsIScriptSecurityManager::ALLOW_CHROME);
|
||||
if (NS_FAILED(rv)) { // failure is normal here; don't warn
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
LOG((" Passed security check"));
|
||||
|
||||
// Check with content policy
|
||||
if (aSourceURI) {
|
||||
// Check with content policy
|
||||
|
||||
PRInt16 shouldLoad = nsIContentPolicy::ACCEPT;
|
||||
rv = NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_STYLESHEET,
|
||||
aTargetURI,
|
||||
aSourceURI,
|
||||
aContext,
|
||||
NS_LITERAL_CSTRING("text/css"),
|
||||
nsnull, //extra param
|
||||
&shouldLoad,
|
||||
nsContentUtils::GetContentPolicy());
|
||||
PRInt16 shouldLoad = nsIContentPolicy::ACCEPT;
|
||||
rv = NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_STYLESHEET,
|
||||
aTargetURI,
|
||||
aSourceURI,
|
||||
aContext,
|
||||
NS_LITERAL_CSTRING("text/css"),
|
||||
nsnull, //extra param
|
||||
&shouldLoad,
|
||||
nsContentUtils::GetContentPolicy());
|
||||
|
||||
if (NS_FAILED(rv) || NS_CP_REJECTED(shouldLoad)) {
|
||||
LOG((" Load blocked by content policy"));
|
||||
return NS_ERROR_CONTENT_BLOCKED;
|
||||
if (NS_FAILED(rv) || NS_CP_REJECTED(shouldLoad)) {
|
||||
LOG((" Load blocked by content policy"));
|
||||
return NS_ERROR_CONTENT_BLOCKED;
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1976,28 +1983,39 @@ CSSLoaderImpl::LoadSheetSync(nsIURI* aURL, PRBool aAllowUnsafeRules,
|
|||
nsICSSStyleSheet** aSheet)
|
||||
{
|
||||
LOG(("CSSLoaderImpl::LoadSheetSync"));
|
||||
return InternalLoadNonDocumentSheet(aURL, aAllowUnsafeRules, aSheet, nsnull);
|
||||
return InternalLoadNonDocumentSheet(aURL, aAllowUnsafeRules, nsnull,
|
||||
nsnull, aSheet, nsnull);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
CSSLoaderImpl::LoadSheet(nsIURI* aURL, nsICSSLoaderObserver* aObserver,
|
||||
CSSLoaderImpl::LoadSheet(nsIURI* aURL,
|
||||
nsIURI* aOriginURI,
|
||||
nsIPrincipal* aOriginPrincipal,
|
||||
nsICSSLoaderObserver* aObserver,
|
||||
nsICSSStyleSheet** aSheet)
|
||||
{
|
||||
LOG(("CSSLoaderImpl::LoadSheet(aURL, aObserver, aSheet) api call"));
|
||||
NS_PRECONDITION(aSheet, "aSheet is null");
|
||||
return InternalLoadNonDocumentSheet(aURL, PR_FALSE, aSheet, aObserver);
|
||||
return InternalLoadNonDocumentSheet(aURL, PR_FALSE, aOriginURI,
|
||||
aOriginPrincipal, aSheet, aObserver);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
CSSLoaderImpl::LoadSheet(nsIURI* aURL, nsICSSLoaderObserver* aObserver)
|
||||
CSSLoaderImpl::LoadSheet(nsIURI* aURL,
|
||||
nsIURI* aOriginURI,
|
||||
nsIPrincipal* aOriginPrincipal,
|
||||
nsICSSLoaderObserver* aObserver)
|
||||
{
|
||||
LOG(("CSSLoaderImpl::LoadSheet(aURL, aObserver) api call"));
|
||||
return InternalLoadNonDocumentSheet(aURL, PR_FALSE, nsnull, aObserver);
|
||||
return InternalLoadNonDocumentSheet(aURL, PR_FALSE, aOriginURI,
|
||||
aOriginPrincipal, nsnull, aObserver);
|
||||
}
|
||||
|
||||
nsresult
|
||||
CSSLoaderImpl::InternalLoadNonDocumentSheet(nsIURI* aURL,
|
||||
PRBool aAllowUnsafeRules,
|
||||
nsIURI* aOriginURI,
|
||||
nsIPrincipal* aOriginPrincipal,
|
||||
nsICSSStyleSheet** aSheet,
|
||||
nsICSSLoaderObserver* aObserver)
|
||||
{
|
||||
|
@ -2016,12 +2034,17 @@ CSSLoaderImpl::InternalLoadNonDocumentSheet(nsIURI* aURL,
|
|||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
nsresult rv = CheckLoadAllowed(aOriginURI, aOriginPrincipal, aURL, mDocument);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
StyleSheetState state;
|
||||
nsCOMPtr<nsICSSStyleSheet> sheet;
|
||||
PRBool syncLoad = (aObserver == nsnull);
|
||||
|
||||
nsresult rv = CreateSheet(aURL, nsnull, nsnull, syncLoad, state,
|
||||
getter_AddRefs(sheet));
|
||||
rv = CreateSheet(aURL, nsnull, nsnull, syncLoad, state,
|
||||
getter_AddRefs(sheet));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
const nsSubstring& empty = EmptyString();
|
||||
|
@ -2040,7 +2063,8 @@ CSSLoaderImpl::InternalLoadNonDocumentSheet(nsIURI* aURL,
|
|||
}
|
||||
|
||||
SheetLoadData* data =
|
||||
new SheetLoadData(this, aURL, sheet, syncLoad, aAllowUnsafeRules, aObserver);
|
||||
new SheetLoadData(this, aURL, sheet, syncLoad, aAllowUnsafeRules,
|
||||
aObserver, aOriginPrincipal);
|
||||
|
||||
if (!data) {
|
||||
sheet->SetComplete();
|
||||
|
|
|
@ -135,7 +135,8 @@ public:
|
|||
nsICSSStyleSheet* aSheet,
|
||||
PRBool aSyncLoad,
|
||||
PRBool aAllowUnsafeRules,
|
||||
nsICSSLoaderObserver* aObserver);
|
||||
nsICSSLoaderObserver* aObserver,
|
||||
nsIPrincipal* aLoaderPrincipal);
|
||||
|
||||
already_AddRefed<nsIURI> GetReferrerURI();
|
||||
|
||||
|
@ -340,10 +341,16 @@ public:
|
|||
NS_IMETHOD LoadSheetSync(nsIURI* aURL, PRBool aAllowUnsafeRules,
|
||||
nsICSSStyleSheet** aSheet);
|
||||
|
||||
NS_IMETHOD LoadSheet(nsIURI* aURL, nsICSSLoaderObserver* aObserver,
|
||||
NS_IMETHOD LoadSheet(nsIURI* aURL,
|
||||
nsIURI* aOriginURI,
|
||||
nsIPrincipal* aOriginPrincipal,
|
||||
nsICSSLoaderObserver* aObserver,
|
||||
nsICSSStyleSheet** aSheet);
|
||||
|
||||
NS_IMETHOD LoadSheet(nsIURI* aURL, nsICSSLoaderObserver* aObserver);
|
||||
NS_IMETHOD LoadSheet(nsIURI* aURL,
|
||||
nsIURI* aOriginURI,
|
||||
nsIPrincipal* aOriginPrincipal,
|
||||
nsICSSLoaderObserver* aObserver);
|
||||
|
||||
// stop loading all sheets
|
||||
NS_IMETHOD Stop(void);
|
||||
|
@ -372,6 +379,8 @@ public:
|
|||
PRBool IsAlternate(const nsAString& aTitle, PRBool aHasAlternateRel);
|
||||
|
||||
private:
|
||||
// Note: null aSourceURI or aSourcePrincipal indicates that the content
|
||||
// policy or CheckLoadURI checks (respectively) should be skipped.
|
||||
nsresult CheckLoadAllowed(nsIURI* aSourceURI,
|
||||
nsIPrincipal* aSourcePrincipal,
|
||||
nsIURI* aTargetURI,
|
||||
|
@ -409,6 +418,8 @@ private:
|
|||
|
||||
nsresult InternalLoadNonDocumentSheet(nsIURI* aURL,
|
||||
PRBool aAllowUnsafeRules,
|
||||
nsIURI* aOriginURI,
|
||||
nsIPrincipal* aOriginPrincipal,
|
||||
nsICSSStyleSheet** aSheet,
|
||||
nsICSSLoaderObserver* aObserver);
|
||||
|
||||
|
|
|
@ -55,12 +55,13 @@ class nsIUnicharInputStream;
|
|||
class nsICSSLoaderObserver;
|
||||
class nsMediaList;
|
||||
class nsICSSImportRule;
|
||||
class nsIPrincipal;
|
||||
|
||||
// IID for the nsICSSLoader interface
|
||||
// 5da3a869-270c-4f10-97d1-99eaa150eb4e
|
||||
// eed4ac28-0add-43a7-84bf-fb53109ae40c
|
||||
#define NS_ICSS_LOADER_IID \
|
||||
{ 0x5da3a869, 0x270c, 0x4f10, \
|
||||
{ 0x97, 0xd1, 0x99, 0xea, 0xa1, 0x50, 0xeb, 0x4e } }
|
||||
{ 0xeed4ac28, 0x0add, 0x43a7, \
|
||||
{ 0x84, 0xbf, 0xfb, 0x53, 0x10, 0x9a, 0xe4, 0x0c } }
|
||||
|
||||
typedef void (*nsCSSLoaderCallbackFunc)(nsICSSStyleSheet* aSheet, void *aData, PRBool aDidNotify);
|
||||
|
||||
|
@ -202,19 +203,31 @@ public:
|
|||
* sheets not associated with a document.
|
||||
*
|
||||
* @param aURL the URL of the sheet to load
|
||||
* @param aOriginURI the URI the load originated from, for content policy
|
||||
* checks. This can be null to indicate that these checks
|
||||
* should be skipped.
|
||||
* @param aOriginPrincipal the principal to use for security checks. This
|
||||
* can be null to indicate that these checks should
|
||||
* be skipped.
|
||||
* @param aObserver the observer to notify when the load completes.
|
||||
* Must not be null.
|
||||
* @param [out] aSheet the sheet to load. Note that the sheet may well
|
||||
* not be loaded by the time this method returns.
|
||||
*/
|
||||
NS_IMETHOD LoadSheet(nsIURI* aURL, nsICSSLoaderObserver* aObserver,
|
||||
NS_IMETHOD LoadSheet(nsIURI* aURL,
|
||||
nsIURI* aOriginURI,
|
||||
nsIPrincipal* aOriginPrincipal,
|
||||
nsICSSLoaderObserver* aObserver,
|
||||
nsICSSStyleSheet** aSheet) = 0;
|
||||
|
||||
/**
|
||||
* Same as above, to be used when the caller doesn't care about the
|
||||
* not-yet-loaded sheet.
|
||||
*/
|
||||
NS_IMETHOD LoadSheet(nsIURI* aURL, nsICSSLoaderObserver* aObserver) = 0;
|
||||
NS_IMETHOD LoadSheet(nsIURI* aURL,
|
||||
nsIURI* aOriginURI,
|
||||
nsIPrincipal* aOriginPrincipal,
|
||||
nsICSSLoaderObserver* aObserver) = 0;
|
||||
|
||||
/**
|
||||
* Stop loading all sheets. All nsICSSLoaderObservers involved will be
|
||||
|
|
Загрузка…
Ссылка в новой задаче