From 0a58794dfe8b8dcae1face0489e8db2317917d0c Mon Sep 17 00:00:00 2001 From: "blizzard%redhat.com" Date: Thu, 2 Nov 2000 22:28:23 +0000 Subject: [PATCH] Fix bug #57197, crash when opening a url when only the mail/news window is open by using the uri loader to do all of the heavy lifting. r=alecf, sr=mscott --- widget/src/gtk/nsGtkMozRemoteHelper.cpp | 188 +++++++++++++++++++----- 1 file changed, 154 insertions(+), 34 deletions(-) diff --git a/widget/src/gtk/nsGtkMozRemoteHelper.cpp b/widget/src/gtk/nsGtkMozRemoteHelper.cpp index 7f397b938441..6011c9ee8dfc 100644 --- a/widget/src/gtk/nsGtkMozRemoteHelper.cpp +++ b/widget/src/gtk/nsGtkMozRemoteHelper.cpp @@ -37,6 +37,11 @@ #include "nsIAllocator.h" #include "nsXPIDLString.h" #include "nsIWebNavigation.h" +#include "nsIURIContentListener.h" +#include "nsIChannel.h" +#include "nsIURILoader.h" +#include "nsCURILoader.h" +#include "nsNetUtil.h" #ifdef MOZ_MAIL_NEWS @@ -69,6 +74,126 @@ static char *s509InternalError = "509 internal error"; static NS_DEFINE_IID(kAppShellServiceCID, NS_APPSHELL_SERVICE_CID); static NS_DEFINE_CID(kWindowMediatorCID, NS_WINDOWMEDIATOR_CID); +class RemoteHelperContentListener : public nsIURIContentListener, + public nsIInterfaceRequestor +{ + NS_DECL_ISUPPORTS + NS_DECL_NSIURICONTENTLISTENER + NS_DECL_NSIINTERFACEREQUESTOR + + RemoteHelperContentListener(); + virtual ~RemoteHelperContentListener(); + +private: + nsCOMPtr mLoadCookie; +}; + +NS_INTERFACE_MAP_BEGIN(RemoteHelperContentListener) + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIURIContentListener) + NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor) +NS_INTERFACE_MAP_END + +NS_IMPL_ADDREF(RemoteHelperContentListener) +NS_IMPL_RELEASE(RemoteHelperContentListener) + +RemoteHelperContentListener::RemoteHelperContentListener() +{ + NS_INIT_ISUPPORTS(); +} + +RemoteHelperContentListener::~RemoteHelperContentListener() +{ +} + +// nsIURIContentListener + +NS_IMETHODIMP +RemoteHelperContentListener::OnStartURIOpen(nsIURI *aURI, + const char *aWindowTarget, + PRBool *aAbortOpen) +{ + return NS_OK; +} + +NS_IMETHODIMP +RemoteHelperContentListener::GetProtocolHandler(nsIURI *aURI, + nsIProtocolHandler **aProtocolHandler) +{ + *aProtocolHandler = nsnull; + return NS_OK; +} + +NS_IMETHODIMP +RemoteHelperContentListener::DoContent(const char *aContentType, + nsURILoadCommand aCommand, + const char *aWindowTarget, + nsIChannel *aOpenedChannel, + nsIStreamListener **aContentHandler, + PRBool *aAbortProcess) +{ + NS_NOTREACHED("RemoteHelperContentListener::DoContent"); + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +RemoteHelperContentListener::IsPreferred(const char *aContentType, + nsURILoadCommand aCommand, + const char *aWindowTarget, + char **aDesiredContentType, + PRBool *_retval) +{ + NS_NOTREACHED("RemoteHelperContentListener::IsPreferred"); + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +RemoteHelperContentListener::CanHandleContent(const char *aContentType, + nsURILoadCommand aCommand, + const char *aWindowTarget, + char **aDesiredContentType, + PRBool *_retval) +{ + NS_NOTREACHED("RemoteHelperContentListener::CanHandleContent"); + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +RemoteHelperContentListener::GetLoadCookie(nsISupports * *aLoadCookie) +{ + *aLoadCookie = mLoadCookie; + NS_IF_ADDREF(*aLoadCookie); + return NS_OK; +} + +NS_IMETHODIMP +RemoteHelperContentListener::SetLoadCookie(nsISupports * aLoadCookie) +{ + mLoadCookie = aLoadCookie; + return NS_OK; +} + +NS_IMETHODIMP +RemoteHelperContentListener::GetParentContentListener(nsIURIContentListener * *aParentContentListener) +{ + *aParentContentListener = nsnull; + return NS_OK; +} + +NS_IMETHODIMP +RemoteHelperContentListener::SetParentContentListener(nsIURIContentListener * aParentContentListener) +{ + return NS_OK; +} + +// nsIInterfaceRequestor +NS_IMETHODIMP +RemoteHelperContentListener::GetInterface(const nsIID & aIID, + void * *aInstancePtr) +{ + NS_ENSURE_ARG_POINTER(aInstancePtr); + return QueryInterface(aIID, aInstancePtr); +} + nsGtkMozRemoteHelper::nsGtkMozRemoteHelper() { EnsureAtoms(); @@ -558,44 +683,39 @@ nsGtkMozRemoteHelper::OpenURL (const char *aURL, PRBool aNewWindow, PRBoo if (NS_FAILED(rv)) return NS_ERROR_FAILURE; } + // otherwise, pass it off to the default handler else { - nsCOMPtr lastUsedWindow; - nsCOMPtr innerWindow; - nsCOMPtr globalObject; - nsCOMPtr docShell; - nsCOMPtr uri; - // get the most recently used window - rv = GetLastBrowserWindow(getter_AddRefs(lastUsedWindow)); - if (NS_FAILED(rv)) + // get our uri loader service + nsCOMPtr loader (do_GetService(NS_URI_LOADER_CONTRACTID)); + NS_ENSURE_TRUE(loader, NS_ERROR_FAILURE); + + RemoteHelperContentListener *listener; + listener = new RemoteHelperContentListener(); + if (!listener) return NS_ERROR_FAILURE; - // get the content area for that window - rv = lastUsedWindow->Get_content(getter_AddRefs(innerWindow)); - if (NS_FAILED(rv)) - return NS_ERROR_FAILURE; - // get the script global object for that window - globalObject = do_QueryInterface(innerWindow); - if (!globalObject) - return NS_ERROR_FAILURE; - // get the docshell for that window - globalObject->GetDocShell(getter_AddRefs(docShell)); - if (!docShell) - return NS_ERROR_FAILURE; - // load the url + + // we own it + NS_ADDREF(listener); + nsCOMPtr listenerRef(do_QueryInterface((nsIURIContentListener *)listener)); + // now the listenerRef is the only reference + NS_RELEASE(listener); + + // create our uri object + nsCOMPtr uri; rv = NS_NewURI(getter_AddRefs(uri), aURL); - if (NS_FAILED(rv)) - return NS_ERROR_FAILURE; - // go, baby, go! - rv = docShell->LoadURI(uri, nsnull, nsIWebNavigation::LOAD_FLAGS_NONE); - if (NS_FAILED(rv)) - return NS_ERROR_FAILURE; - // raise the window, if requested - if (raiseWindow) - { - rv = lastUsedWindow->GetAttention(); - if (NS_FAILED(rv)) - return NS_ERROR_FAILURE; - } + NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE); + + // open a channel + nsCOMPtr channel; + rv = NS_OpenURI (getter_AddRefs(channel), uri); + NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE); + + // load it + loader->OpenURI(channel, nsIURILoader::viewUserClick, + nsnull, /* target */ + listenerRef); /* window */ + } return NS_OK; }