зеркало из https://github.com/mozilla/pjs.git
Allow certain restricted loads in unload events. Bug 409888, r+sr=jst
This commit is contained in:
Родитель
3ce4adc841
Коммит
5e87eed68a
|
@ -678,7 +678,9 @@ nsDocShell::LoadURI(nsIURI * aURI,
|
|||
PRUint32 aLoadFlags,
|
||||
PRBool aFirstParty)
|
||||
{
|
||||
if (!IsNavigationAllowed()) {
|
||||
// Note: we allow loads to get through here even if mFiredUnloadEvent is
|
||||
// true; that case will get handled in LoadInternal or LoadHistoryEntry.
|
||||
if (IsPrintingOrPP()) {
|
||||
return NS_OK; // JS may not handle returning of an error code
|
||||
}
|
||||
nsresult rv;
|
||||
|
@ -3603,6 +3605,10 @@ nsDocShell::Destroy()
|
|||
}
|
||||
}
|
||||
|
||||
// Make sure to blow away our mLoadingURI just in case. No loads
|
||||
// from inside this pagehide.
|
||||
mLoadingURI = nsnull;
|
||||
|
||||
// Fire unload event before we blow anything away.
|
||||
(void) FirePageHideNotification(PR_TRUE);
|
||||
|
||||
|
@ -5138,6 +5144,10 @@ nsDocShell::CreateAboutBlankContentViewer(nsIPrincipal* aPrincipal)
|
|||
|
||||
mSavingOldViewer = CanSavePresentation(LOAD_NORMAL, nsnull, nsnull);
|
||||
|
||||
// Make sure to blow away our mLoadingURI just in case. No loads
|
||||
// from inside this pagehide.
|
||||
mLoadingURI = nsnull;
|
||||
|
||||
// Notify the current document that it is about to be unloaded!!
|
||||
//
|
||||
// It is important to fire the unload() notification *before* any state
|
||||
|
@ -5554,6 +5564,10 @@ nsDocShell::RestoreFromHistory()
|
|||
// pagehide or unload.
|
||||
nsCOMPtr<nsISHEntry> origLSHE = mLSHE;
|
||||
|
||||
// Make sure to blow away our mLoadingURI just in case. No loads
|
||||
// from inside this pagehide.
|
||||
mLoadingURI = nsnull;
|
||||
|
||||
// Notify the old content viewer that it's being hidden.
|
||||
FirePageHideNotification(!mSavingOldViewer);
|
||||
|
||||
|
@ -5916,7 +5930,14 @@ nsDocShell::CreateContentViewer(const char *aContentType,
|
|||
mSavingOldViewer = CanSavePresentation(mLoadType, request, doc);
|
||||
}
|
||||
|
||||
NS_ASSERTION(!mLoadingURI, "Re-entering unload?");
|
||||
|
||||
nsCOMPtr<nsIChannel> aOpenedChannel = do_QueryInterface(request);
|
||||
if (aOpenedChannel) {
|
||||
aOpenedChannel->GetURI(getter_AddRefs(mLoadingURI));
|
||||
}
|
||||
FirePageHideNotification(!mSavingOldViewer);
|
||||
mLoadingURI = nsnull;
|
||||
|
||||
// Set mFiredUnloadEvent = PR_FALSE so that the unload handler for the
|
||||
// *new* document will fire.
|
||||
|
@ -5927,8 +5948,6 @@ nsDocShell::CreateContentViewer(const char *aContentType,
|
|||
// notifications before we've called Embed(). See bug 284993.
|
||||
mURIResultedInDocument = PR_TRUE;
|
||||
|
||||
nsCOMPtr<nsIChannel> aOpenedChannel = do_QueryInterface(request);
|
||||
|
||||
PRBool onLocationChangeNeeded = OnLoadingSite(aOpenedChannel, PR_FALSE);
|
||||
|
||||
// let's try resetting the load group if we need to...
|
||||
|
@ -6450,6 +6469,60 @@ nsDocShell::CheckLoadingPermissions()
|
|||
//*****************************************************************************
|
||||
// nsDocShell: Site Loading
|
||||
//*****************************************************************************
|
||||
class InternalLoadEvent : public nsRunnable
|
||||
{
|
||||
public:
|
||||
InternalLoadEvent(nsDocShell* aDocShell, nsIURI * aURI, nsIURI * aReferrer,
|
||||
nsISupports * aOwner, PRUint32 aFlags,
|
||||
const PRUnichar *aWindowTarget, const char* aTypeHint,
|
||||
nsIInputStream * aPostData,
|
||||
nsIInputStream * aHeadersData, PRUint32 aLoadType,
|
||||
nsISHEntry * aSHEntry, PRBool aFirstParty) :
|
||||
mDocShell(aDocShell),
|
||||
mURI(aURI),
|
||||
mReferrer(aReferrer),
|
||||
mOwner(aOwner),
|
||||
mFlags(aFlags),
|
||||
mPostData(aPostData),
|
||||
mHeadersData(aHeadersData),
|
||||
mLoadType(aLoadType),
|
||||
mSHEntry(aSHEntry),
|
||||
mFirstParty(aFirstParty)
|
||||
{
|
||||
// Make sure to keep null things null as needed
|
||||
if (aWindowTarget) {
|
||||
mWindowTarget = aWindowTarget;
|
||||
}
|
||||
if (aTypeHint) {
|
||||
mTypeHint = aTypeHint;
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHOD Run() {
|
||||
return mDocShell->InternalLoad(mURI, mReferrer, mOwner, mFlags,
|
||||
mWindowTarget.get(), mTypeHint.get(),
|
||||
mPostData, mHeadersData, mLoadType,
|
||||
mSHEntry, mFirstParty, nsnull, nsnull);
|
||||
}
|
||||
|
||||
private:
|
||||
nsRefPtr<nsDocShell> mDocShell;
|
||||
nsCOMPtr<nsIURI> mURI;
|
||||
nsCOMPtr<nsIURI> mReferrer;
|
||||
nsCOMPtr<nsISupports> mOwner;
|
||||
PRUint32 mFlags;
|
||||
|
||||
// Use IDL strings so .get() returns null by default
|
||||
nsXPIDLString mWindowTarget;
|
||||
nsXPIDLCString mTypeHint;
|
||||
|
||||
nsCOMPtr<nsIInputStream> mPostData;
|
||||
nsCOMPtr<nsIInputStream> mHeadersData;
|
||||
PRUint32 mLoadType;
|
||||
nsCOMPtr<nsISHEntry> mSHEntry;
|
||||
PRBool mFirstParty;
|
||||
};
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::InternalLoad(nsIURI * aURI,
|
||||
nsIURI * aReferrer,
|
||||
|
@ -6465,10 +6538,6 @@ nsDocShell::InternalLoad(nsIURI * aURI,
|
|||
nsIDocShell** aDocShell,
|
||||
nsIRequest** aRequest)
|
||||
{
|
||||
if (mFiredUnloadEvent) {
|
||||
return NS_OK; // JS may not handle returning of an error code
|
||||
}
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
#ifdef PR_LOGGING
|
||||
|
@ -6496,6 +6565,21 @@ nsDocShell::InternalLoad(nsIURI * aURI,
|
|||
|
||||
NS_ENSURE_TRUE(!mIsBeingDestroyed, NS_ERROR_NOT_AVAILABLE);
|
||||
|
||||
if (mFiredUnloadEvent) {
|
||||
if (IsOKToLoadURI(aURI)) {
|
||||
// Do this asynchronously
|
||||
nsCOMPtr<nsIRunnable> ev =
|
||||
new InternalLoadEvent(this, aURI, aReferrer, aOwner, aFlags,
|
||||
aWindowTarget, aTypeHint,
|
||||
aPostData, aHeadersData, aLoadType,
|
||||
aSHEntry, aFirstParty);
|
||||
return NS_DispatchToCurrentThread(ev);
|
||||
}
|
||||
|
||||
// Just ignore this load attempt
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// wyciwyg urls can only be loaded through history. Any normal load of
|
||||
// wyciwyg through docshell is illegal. Disallow such loads.
|
||||
if (aLoadType & LOAD_CMD_NORMAL) {
|
||||
|
@ -8064,6 +8148,10 @@ nsDocShell::AddToSessionHistory(nsIURI * aURI,
|
|||
NS_IMETHODIMP
|
||||
nsDocShell::LoadHistoryEntry(nsISHEntry * aEntry, PRUint32 aLoadType)
|
||||
{
|
||||
if (!IsNavigationAllowed()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
nsCOMPtr<nsIInputStream> postData;
|
||||
nsCOMPtr<nsIURI> referrerURI;
|
||||
|
@ -9211,6 +9299,26 @@ nsDocShell::IsAboutBlank(nsIURI* aURI)
|
|||
return str.EqualsLiteral("about:blank");
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsDocShell::IsOKToLoadURI(nsIURI* aURI)
|
||||
{
|
||||
NS_PRECONDITION(aURI, "Must have a URI!");
|
||||
|
||||
if (!mFiredUnloadEvent) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
if (!mLoadingURI) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIScriptSecurityManager> secMan =
|
||||
do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID);
|
||||
return
|
||||
secMan &&
|
||||
NS_SUCCEEDED(secMan->CheckSameOriginURI(aURI, mLoadingURI, PR_FALSE));
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
// nsClassifierCallback
|
||||
//*****************************************************************************
|
||||
|
|
|
@ -513,6 +513,11 @@ protected:
|
|||
// Check whether aURI is about:blank
|
||||
static PRBool IsAboutBlank(nsIURI* aURI);
|
||||
|
||||
// Call this when a URI load is handed to us (via OnLinkClick or
|
||||
// InternalLoad). This makes sure that we're not inside unload, or that if
|
||||
// we are it's still OK to load this URI.
|
||||
PRBool IsOKToLoadURI(nsIURI* aURI);
|
||||
|
||||
protected:
|
||||
// Override the parent setter from nsDocLoader
|
||||
virtual nsresult SetDocLoaderParent(nsDocLoader * aLoader);
|
||||
|
@ -642,6 +647,13 @@ protected:
|
|||
// Suspends/resumes channels based on the URI classifier.
|
||||
nsRefPtr<nsClassifierCallback> mClassifier;
|
||||
|
||||
// The URI we're currently loading. This is only relevant during the
|
||||
// firing of a pagehide/unload. The caller of FirePageHideNotification()
|
||||
// is responsible for setting it and unsetting it. It may be null if the
|
||||
// pagehide/unload is happening for some reason other than just loading a
|
||||
// new URI.
|
||||
nsCOMPtr<nsIURI> mLoadingURI;
|
||||
|
||||
// WEAK REFERENCES BELOW HERE.
|
||||
// Note these are intentionally not addrefd. Doing so will create a cycle.
|
||||
// For that reasons don't use nsCOMPtr.
|
||||
|
|
|
@ -766,7 +766,7 @@ nsWebShell::OnLinkClick(nsIContent* aContent,
|
|||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "wrong thread");
|
||||
|
||||
if (mFiredUnloadEvent) {
|
||||
if (!IsOKToLoadURI(aURI)) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -797,7 +797,7 @@ nsWebShell::OnLinkClickSync(nsIContent *aContent,
|
|||
*aRequest = nsnull;
|
||||
}
|
||||
|
||||
if (mFiredUnloadEvent) {
|
||||
if (!IsOKToLoadURI(aURI)) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче