diff --git a/mozilla/extensions/psm-glue/src/nsPSMComponent.cpp b/mozilla/extensions/psm-glue/src/nsPSMComponent.cpp index 1bd8a871213..279b83775ee 100644 --- a/mozilla/extensions/psm-glue/src/nsPSMComponent.cpp +++ b/mozilla/extensions/psm-glue/src/nsPSMComponent.cpp @@ -891,7 +891,9 @@ nsPSMComponent::HandleContent(const char * aContentType, return NS_ERROR_FAILURE; } -NS_IMPL_ISUPPORTS(CertContentListener, NS_GET_IID(nsIURIContentListener)); +NS_IMPL_ISUPPORTS2(CertContentListener, + nsIURIContentListener, + nsISupportsWeakReference); CertContentListener::CertContentListener() diff --git a/mozilla/extensions/psm-glue/src/nsPSMComponent.h b/mozilla/extensions/psm-glue/src/nsPSMComponent.h index 7b1a0da9c41..283c4b04c4e 100644 --- a/mozilla/extensions/psm-glue/src/nsPSMComponent.h +++ b/mozilla/extensions/psm-glue/src/nsPSMComponent.h @@ -47,7 +47,9 @@ // Now we need a content listener to register //-------------------------------------------- -class CertContentListener : public nsIURIContentListener { +class CertContentListener : public nsIURIContentListener, + public nsSupportsWeakReference +{ public: CertContentListener(); virtual ~CertContentListener(); diff --git a/mozilla/mailnews/base/src/nsMsgWindow.cpp b/mozilla/mailnews/base/src/nsMsgWindow.cpp index e3a2107794a..150ce215764 100644 --- a/mozilla/mailnews/base/src/nsMsgWindow.cpp +++ b/mozilla/mailnews/base/src/nsMsgWindow.cpp @@ -55,7 +55,10 @@ static NS_DEFINE_CID(kTransactionManagerCID, NS_TRANSACTIONMANAGER_CID); static NS_DEFINE_CID(kComponentManagerCID, NS_COMPONENTMANAGER_CID); -NS_IMPL_THREADSAFE_ISUPPORTS2(nsMsgWindow, nsIMsgWindow, nsIURIContentListener) +NS_IMPL_THREADSAFE_ISUPPORTS3(nsMsgWindow, + nsIMsgWindow, + nsIURIContentListener, + nsISupportsWeakReference) nsMsgWindow::nsMsgWindow() { diff --git a/mozilla/mailnews/base/src/nsMsgWindow.h b/mozilla/mailnews/base/src/nsMsgWindow.h index 67c1e8ea3a2..ee5e0fea07a 100644 --- a/mozilla/mailnews/base/src/nsMsgWindow.h +++ b/mozilla/mailnews/base/src/nsMsgWindow.h @@ -34,7 +34,10 @@ #include "nsCOMPtr.h" -class nsMsgWindow : public nsIMsgWindow, public nsIURIContentListener { +class nsMsgWindow : public nsIMsgWindow, + public nsIURIContentListener, + public nsSupportsWeakReference +{ public: diff --git a/mozilla/uriloader/base/nsURILoader.cpp b/mozilla/uriloader/base/nsURILoader.cpp index 96f7cfbcbc4..03d19594e56 100644 --- a/mozilla/uriloader/base/nsURILoader.cpp +++ b/mozilla/uriloader/base/nsURILoader.cpp @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode:nil; c-basic-offset: 2 -*- * * The contents of this file are subject to the Netscape Public * License Version 1.1 (the "License"); you may not use this file @@ -42,7 +42,6 @@ #include "nsIDocShellTreeItem.h" #include "nsIDocShellTreeOwner.h" -#include "nsVoidArray.h" #include "nsXPIDLString.h" #include "nsString.h" @@ -455,7 +454,7 @@ nsresult nsDocumentOpenInfo::RetargetOutput(nsIRequest *request, const char * aS nsURILoader::nsURILoader() { NS_INIT_ISUPPORTS(); - m_listeners = new nsVoidArray(); + NS_NewISupportsArray(getter_AddRefs(m_listeners)); // Check pref to see if we should prevent frameset spoofing mValidateOrigin = PR_TRUE; // secure by default, pref disables check @@ -467,8 +466,6 @@ nsURILoader::nsURILoader() nsURILoader::~nsURILoader() { - if (m_listeners) - delete m_listeners; } NS_IMPL_ADDREF(nsURILoader); @@ -482,18 +479,25 @@ NS_INTERFACE_MAP_END NS_IMETHODIMP nsURILoader::RegisterContentListener(nsIURIContentListener * aContentListener) { nsresult rv = NS_OK; - if (m_listeners) - m_listeners->AppendElement(aContentListener); - else - rv = NS_ERROR_FAILURE; + if (!m_listeners) return NS_ERROR_FAILURE; + + nsWeakPtr weakListener = do_GetWeakReference(aContentListener); + NS_ASSERTION(weakListener, "your URIContentListener must support weak refs!\n"); + + if (weakListener) + m_listeners->AppendElement(weakListener); return rv; } NS_IMETHODIMP nsURILoader::UnRegisterContentListener(nsIURIContentListener * aContentListener) { - if (m_listeners) - m_listeners->RemoveElement(aContentListener); + if (!m_listeners) return NS_OK; + + nsWeakPtr weakListener = do_GetWeakReference(aContentListener); + if (weakListener) + m_listeners->RemoveElement(weakListener); + return NS_OK; } @@ -976,31 +980,35 @@ NS_IMETHODIMP nsURILoader::DispatchContent(const char * aContentType, NS_ENSURE_ARG(aContentType); NS_ENSURE_ARG(request); - // okay, now we've discovered the content type. We need to do the following: - // (1) We always start with the original content listener (if any) that originated the request - // and then ask if it can handle the content. - // (2) if it can't, we'll move on to the registered content listeners and give - // them a crack at handling the content. - - // (3) if we cannot find a registered content lister to handle the type, then we move on to - // phase II which is to try to find a content handler in the registry for the content type. - // hitting this phase usually means we'll be creating a new window or handing off to an - // external application. + // okay, now we've discovered the content type. We need to do the + // following: + // (1) We always start with the original content listener (if any) + // that originated the request and then ask if it can handle the + // content. + // (2) if it can't, we'll move on to the registered content + // listeners and give them a crack at handling the content. + // (3) if we cannot find a registered content lister to handle the + // type, then we move on to phase II which is to try to find a + // content handler in the registry for the content type. + // hitting this phase usually means we'll be creating a new + // window or handing off to an external application. nsresult rv = NS_OK; nsCOMPtr listenerToUse = aContentListener; PRBool skipRetargetingSearch = PR_FALSE; - // How do we determine whether we need to ask any registered content listeners if they - // want a crack at the content? - // (1) if the window target is blank or new, then we don't want to ask... + // How do we determine whether we need to ask any registered content + // listeners if they want a crack at the content? + // (1) if the window target is blank or new, then we don't want to + // ask... if (!nsCRT::strcasecmp(aWindowTarget, "_blank") || !nsCRT::strcasecmp(aWindowTarget, "_new")) skipRetargetingSearch = PR_TRUE; else { - // (2) if the original content listener is NULL and we have a target name then we - // must not be a window open with that target name so skip the content listener search - // and skip to the part that brings up the new window. + // (2) if the original content listener is NULL and we have a + // target name then we must not be a window open with that + // target name so skip the content listener search and skip to + // the part that brings up the new window. if (aWindowTarget && *aWindowTarget && !aContentListener) skipRetargetingSearch = PR_TRUE; } @@ -1014,20 +1022,32 @@ NS_IMETHODIMP nsURILoader::DispatchContent(const char * aContentType, aCommand, aWindowTarget, aContentTypeToUse); - if (!foundContentHandler) // if it can't handle the content, scan through the list of registered listeners + // if it can't handle the content, scan through the list of + // registered listeners + if (!foundContentHandler) { PRInt32 i = 0; // keep looping until we get a content listener back - for(i = 0; i < m_listeners->Count() && !foundContentHandler; i++) + PRUint32 count; m_listeners->Count(&count); + for(i = 0; i < PRInt32(count) && !foundContentHandler; i++) { //nsIURIContentListener's aren't refcounted. - nsIURIContentListener * listener =(nsIURIContentListener*)m_listeners->ElementAt(i); + nsWeakPtr weakListener; + m_listeners->QueryElementAt(i, NS_GET_IID(nsIWeakReference), + getter_AddRefs(weakListener)); + + nsCOMPtr listener = + do_QueryReferent(weakListener); if (listener) { foundContentHandler = ShouldHandleContent(listener, aContentType, aCommand, aWindowTarget, aContentTypeToUse); if (foundContentHandler) listenerToUse = listener; + } else { + // remove from the listener list, and reset i + m_listeners->RemoveElementAt(i); + i--; } } // for loop } // if we can't handle the content diff --git a/mozilla/uriloader/base/nsURILoader.h b/mozilla/uriloader/base/nsURILoader.h index e5a13855460..f740cb85f04 100644 --- a/mozilla/uriloader/base/nsURILoader.h +++ b/mozilla/uriloader/base/nsURILoader.h @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * The contents of this file are subject to the Netscape Public * License Version 1.1 (the "License"); you may not use this file @@ -25,12 +25,11 @@ #include "nsCURILoader.h" #include "nsISupportsUtils.h" +#include "nsISupportsArray.h" #include "nsCOMPtr.h" #include "nsIInterfaceRequestor.h" #include "nsString.h" -class nsVoidArray; - class nsURILoader : public nsIURILoader { public: @@ -43,8 +42,8 @@ public: protected: // we shouldn't need to have an owning ref count on registered // content listeners because they are supposed to unregister themselves - // when they go away. - nsVoidArray * m_listeners; + // when they go away. This array stores weak references + nsCOMPtr m_listeners; // If set, we will try to prevent frame spoofing (set by pref in constructor) PRBool mValidateOrigin;