Bug 251475. Make sure channels don't return null for the originalURI. Initial work by Daniel Kraft <domob@daniel-kraft.net> and Brandon Ferguson <bnferguson@gmail.com>. r+sr=bzbarsky.
authorIan <montague.bugzilla@gmail.com>
Wed, 15 Oct 2008 16:05:23 -0400
changeset 20508 3b4a3bfc99a7167d9017970e1c78bbae12c27455
parent 20507 aa4b3566d739b1b1e272f8e259a259da32472cf2
child 20509 3143e3a43176d86933ea7064ae406915bb82a57b
push idunknown
push userunknown
push dateunknown
bugs251475
milestone1.9.1b2pre
Bug 251475. Make sure channels don't return null for the originalURI. Initial work by Daniel Kraft <domob@daniel-kraft.net> and Brandon Ferguson <bnferguson@gmail.com>. r+sr=bzbarsky.
chrome/src/nsChromeProtocolHandler.cpp
content/html/document/src/nsWyciwygChannel.cpp
embedding/tests/wxEmbed/GeckoProtocolHandler.cpp
modules/libjar/nsJARChannel.cpp
modules/libpr0n/decoders/icon/beos/nsIconChannel.cpp
modules/libpr0n/decoders/icon/mac/nsIconChannel.cpp
modules/libpr0n/decoders/icon/mac/nsIconChannelCocoa.mm
modules/libpr0n/decoders/icon/os2/nsIconChannel.cpp
modules/libpr0n/decoders/icon/win/nsIconChannel.cpp
netwerk/base/public/nsIChannel.idl
netwerk/base/src/nsBaseChannel.cpp
netwerk/base/src/nsBaseChannel.h
netwerk/protocol/http/src/nsHttpChannel.cpp
netwerk/protocol/viewsource/src/nsViewSourceChannel.cpp
uriloader/exthandler/nsExternalProtocolHandler.cpp
--- a/chrome/src/nsChromeProtocolHandler.cpp
+++ b/chrome/src/nsChromeProtocolHandler.cpp
@@ -155,16 +155,17 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsCachedCh
 PRLogModuleInfo* nsCachedChromeChannel::gLog;
 #endif
 
 NS_IMPL_ISUPPORTS3(nsCachedChromeChannel, nsIChannel, nsIRequest,
                    nsCachedChromeChannel)
 
 nsCachedChromeChannel::nsCachedChromeChannel(nsIURI* aURI)
     : mURI(aURI)
+    , mOriginalURI(aURI)
     , mLoadFlags(nsIRequest::LOAD_NORMAL)
     , mStatus(NS_OK)
 {
 #ifdef PR_LOGGING
     if (! gLog)
         gLog = PR_NewLogModule("nsCachedChromeChannel");
 #endif
 
@@ -176,24 +177,25 @@ nsCachedChromeChannel::~nsCachedChromeCh
 {
     LOG(("nsCachedChromeChannel[%p]: destroyed", this));
 }
 
 
 NS_IMETHODIMP
 nsCachedChromeChannel::GetOriginalURI(nsIURI* *aOriginalURI)
 {
-    *aOriginalURI = mOriginalURI ? mOriginalURI : mURI;
+    *aOriginalURI = mOriginalURI;
     NS_ADDREF(*aOriginalURI);
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCachedChromeChannel::SetOriginalURI(nsIURI* aOriginalURI)
 {
+    NS_ENSURE_ARG_POINTER(aOriginalURI);
     mOriginalURI = aOriginalURI;
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCachedChromeChannel::GetURI(nsIURI* *aURI)
 {
     *aURI = mURI;
--- a/content/html/document/src/nsWyciwygChannel.cpp
+++ b/content/html/document/src/nsWyciwygChannel.cpp
@@ -76,16 +76,17 @@ NS_IMPL_ISUPPORTS6(nsWyciwygChannel,
                    nsICacheListener, 
                    nsIWyciwygChannel)
 
 nsresult
 nsWyciwygChannel::Init(nsIURI* uri)
 {
   NS_ENSURE_ARG_POINTER(uri);
   mURI = uri;
+  mOriginalURI = uri;
   return NS_OK;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 // nsIRequest methods:
 ///////////////////////////////////////////////////////////////////////////////
 
 NS_IMETHODIMP
@@ -171,27 +172,29 @@ nsWyciwygChannel::GetLoadFlags(PRUint32 
 ////////////////////////////////////////////////////////////////////////////////
 // nsIChannel methods:
 ///////////////////////////////////////////////////////////////////////////////
 
 NS_IMETHODIMP
 nsWyciwygChannel::GetOriginalURI(nsIURI* *aURI)
 {
   // Let's hope this isn't called before mOriginalURI is set or we will
-  // return the full wyciwyg URI for our originalURI  :S
-  NS_ASSERTION(mOriginalURI, "nsWyciwygChannel::GetOriginalURI - mOriginalURI not set!\n");
-
-  *aURI = mOriginalURI ? mOriginalURI : mURI;
-  NS_IF_ADDREF(*aURI);
+  // return the full wyciwyg URI for our originalURI :S
+  NS_ASSERTION(mOriginalURI != mURI,
+               "nsWyciwygChannel::GetOriginalURI - mOriginalURI not set!\n");
+  
+  *aURI = mOriginalURI;
+  NS_ADDREF(*aURI);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsWyciwygChannel::SetOriginalURI(nsIURI* aURI)
 {
+  NS_ENSURE_ARG_POINTER(aURI);
   mOriginalURI = aURI;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsWyciwygChannel::GetURI(nsIURI* *aURI)
 {
   *aURI = mURI;
--- a/embedding/tests/wxEmbed/GeckoProtocolHandler.cpp
+++ b/embedding/tests/wxEmbed/GeckoProtocolHandler.cpp
@@ -267,16 +267,17 @@ NS_IMETHODIMP GeckoProtocolHandlerImpl::
 ///////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////
 
 NS_IMPL_ISUPPORTS4(GeckoProtocolChannel, nsIRequest, nsIChannel, nsIRequestObserver, nsIStreamListener)
 
 nsresult GeckoProtocolChannel::Init(nsIURI *aURI)
 {
     mURI = aURI;
+    mOriginalURI = aURI;
     return NS_OK;
 }
 
 
 ///////////////////////////////////////////////////////////////////////////////
 // nsIRequest methods
 
 
@@ -323,24 +324,25 @@ GeckoProtocolChannel::Resume()
 
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsIChannel methods:
 
 NS_IMETHODIMP
 GeckoProtocolChannel::GetOriginalURI(nsIURI* *aURI)
 {
-    *aURI = mOriginalURI ? mOriginalURI : mURI;
+    *aURI = mOriginalURI;
     NS_ADDREF(*aURI);
     return NS_OK;
 }
 
 NS_IMETHODIMP
 GeckoProtocolChannel::SetOriginalURI(nsIURI* aURI)
 {
+    NS_ENSURE_ARG_POINTER(aURI);
     mOriginalURI = aURI;
     return NS_OK;
 }
 
 NS_IMETHODIMP
 GeckoProtocolChannel::GetURI(nsIURI* *aURI)
 {
     *aURI = mURI;
--- a/modules/libjar/nsJARChannel.cpp
+++ b/modules/libjar/nsJARChannel.cpp
@@ -257,16 +257,18 @@ NS_IMPL_ISUPPORTS6(nsJARChannel,
 nsresult 
 nsJARChannel::Init(nsIURI *uri)
 {
     nsresult rv;
     mJarURI = do_QueryInterface(uri, &rv);
     if (NS_FAILED(rv))
         return rv;
 
+    mOriginalURI = mJarURI;
+
     // Prevent loading jar:javascript URIs (see bug 290982).
     nsCOMPtr<nsIURI> innerURI;
     rv = mJarURI->GetJARFile(getter_AddRefs(innerURI));
     if (NS_FAILED(rv))
         return rv;
     PRBool isJS;
     rv = innerURI->SchemeIs("javascript", &isJS);
     if (NS_FAILED(rv))
@@ -436,27 +438,25 @@ nsJARChannel::SetLoadGroup(nsILoadGroup 
 
 //-----------------------------------------------------------------------------
 // nsIChannel
 //-----------------------------------------------------------------------------
 
 NS_IMETHODIMP
 nsJARChannel::GetOriginalURI(nsIURI **aURI)
 {
-    if (mOriginalURI)
-        *aURI = mOriginalURI;
-    else
-        *aURI = mJarURI;
-    NS_IF_ADDREF(*aURI);
+    *aURI = mOriginalURI;
+    NS_ADDREF(*aURI);
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsJARChannel::SetOriginalURI(nsIURI *aURI)
 {
+    NS_ENSURE_ARG_POINTER(aURI);
     mOriginalURI = aURI;
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsJARChannel::GetURI(nsIURI **aURI)
 {
     NS_IF_ADDREF(*aURI = mJarURI);
--- a/modules/libpr0n/decoders/icon/beos/nsIconChannel.cpp
+++ b/modules/libpr0n/decoders/icon/beos/nsIconChannel.cpp
@@ -78,17 +78,17 @@ NS_IMPL_THREADSAFE_ISUPPORTS4(nsIconChan
                               nsIRequest,
                               nsIRequestObserver,
                               nsIStreamListener)
 
 nsresult nsIconChannel::Init(nsIURI* uri)
 {
   NS_ASSERTION(uri, "no uri");
   mUrl = uri;
-
+  mOriginalURI = uri;
   nsresult rv;
   mPump = do_CreateInstance(NS_INPUTSTREAMPUMP_CONTRACTID, &rv);
   return rv;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsIRequest methods:
 
@@ -144,23 +144,24 @@ NS_IMETHODIMP nsIconChannel::SetLoadFlag
   return mPump->SetLoadFlags(aLoadAttributes);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsIChannel methods:
 
 NS_IMETHODIMP nsIconChannel::GetOriginalURI(nsIURI* *aURI)
 {
-  *aURI = mOriginalURI ? mOriginalURI : mUrl;
+  *aURI = mOriginalURI;
   NS_ADDREF(*aURI);
   return NS_OK;
 }
 
 NS_IMETHODIMP nsIconChannel::SetOriginalURI(nsIURI* aURI)
 {
+  NS_ENSURE_ARG_POINTER(aURI);
   mOriginalURI = aURI;
   return NS_OK;
 }
 
 NS_IMETHODIMP nsIconChannel::GetURI(nsIURI* *aURI)
 {
   *aURI = mUrl;
   NS_IF_ADDREF(*aURI);
--- a/modules/libpr0n/decoders/icon/mac/nsIconChannel.cpp
+++ b/modules/libpr0n/decoders/icon/mac/nsIconChannel.cpp
@@ -78,17 +78,17 @@ NS_IMPL_THREADSAFE_ISUPPORTS4(nsIconChan
                               nsIRequest,
 			       nsIRequestObserver,
 			       nsIStreamListener)
 
 nsresult nsIconChannel::Init(nsIURI* uri)
 {
   NS_ASSERTION(uri, "no uri");
   mUrl = uri;
-  
+  mOriginalURI = uri;
   nsresult rv;
   mPump = do_CreateInstance(NS_INPUTSTREAMPUMP_CONTRACTID, &rv);
   return rv;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsIRequest methods:
 
@@ -156,23 +156,24 @@ NS_IMETHODIMP nsIconChannel::OnDataAvail
   return NS_OK;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsIChannel methods:
 
 NS_IMETHODIMP nsIconChannel::GetOriginalURI(nsIURI* *aURI)
 {
-  *aURI = mOriginalURI ? mOriginalURI : mUrl;
+  *aURI = mOriginalURI;
   NS_ADDREF(*aURI);
   return NS_OK;
 }
 
 NS_IMETHODIMP nsIconChannel::SetOriginalURI(nsIURI* aURI)
 {
+  NS_ENSURE_ARG_POINTER(aURI);
   mOriginalURI = aURI;
   return NS_OK;
 }
 
 NS_IMETHODIMP nsIconChannel::GetURI(nsIURI* *aURI)
 {
   *aURI = mUrl;
   NS_IF_ADDREF(*aURI);
--- a/modules/libpr0n/decoders/icon/mac/nsIconChannelCocoa.mm
+++ b/modules/libpr0n/decoders/icon/mac/nsIconChannelCocoa.mm
@@ -75,17 +75,17 @@ NS_IMPL_THREADSAFE_ISUPPORTS4(nsIconChan
                               nsIRequest,
 			       nsIRequestObserver,
 			       nsIStreamListener)
 
 nsresult nsIconChannel::Init(nsIURI* uri)
 {
   NS_ASSERTION(uri, "no uri");
   mUrl = uri;
-  
+  mOriginalURI = uri;
   nsresult rv;
   mPump = do_CreateInstance(NS_INPUTSTREAMPUMP_CONTRACTID, &rv);
   return rv;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsIRequest methods:
 
@@ -153,23 +153,24 @@ NS_IMETHODIMP nsIconChannel::OnDataAvail
   return NS_OK;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsIChannel methods:
 
 NS_IMETHODIMP nsIconChannel::GetOriginalURI(nsIURI* *aURI)
 {
-  *aURI = mOriginalURI ? mOriginalURI : mUrl;
+  *aURI = mOriginalURI;
   NS_ADDREF(*aURI);
   return NS_OK;
 }
 
 NS_IMETHODIMP nsIconChannel::SetOriginalURI(nsIURI* aURI)
 {
+  NS_ENSURE_ARG_POINTER(aURI);
   mOriginalURI = aURI;
   return NS_OK;
 }
 
 NS_IMETHODIMP nsIconChannel::GetURI(nsIURI* *aURI)
 {
   *aURI = mUrl;
   NS_IF_ADDREF(*aURI);
--- a/modules/libpr0n/decoders/icon/os2/nsIconChannel.cpp
+++ b/modules/libpr0n/decoders/icon/os2/nsIconChannel.cpp
@@ -103,17 +103,17 @@ NS_IMPL_THREADSAFE_ISUPPORTS4(nsIconChan
                               nsIRequest,
                               nsIRequestObserver,
                               nsIStreamListener)
 
 nsresult nsIconChannel::Init(nsIURI* uri)
 {
   NS_ASSERTION(uri, "no uri");
   mUrl = uri;
-
+  mOriginalURI = uri;
   nsresult rv;
   mPump = do_CreateInstance(NS_INPUTSTREAMPUMP_CONTRACTID, &rv);
   return rv;
 }
 
 //------------------------------------------------------------------------
 // nsIRequest methods:
 
@@ -170,23 +170,24 @@ NS_IMETHODIMP nsIconChannel::SetLoadFlag
   return mPump->SetLoadFlags(aLoadAttributes);
 }
 
 //------------------------------------------------------------------------
 // nsIChannel methods:
 
 NS_IMETHODIMP nsIconChannel::GetOriginalURI(nsIURI* *aURI)
 {
-  *aURI = mOriginalURI ? mOriginalURI : mUrl;
+  *aURI = mOriginalURI;
   NS_ADDREF(*aURI);
   return NS_OK;
 }
 
 NS_IMETHODIMP nsIconChannel::SetOriginalURI(nsIURI* aURI)
 {
+  NS_ENSURE_ARG_POINTER(aURI);
   mOriginalURI = aURI;
   return NS_OK;
 }
 
 NS_IMETHODIMP nsIconChannel::GetURI(nsIURI* *aURI)
 {
   *aURI = mUrl;
   NS_IF_ADDREF(*aURI);
--- a/modules/libpr0n/decoders/icon/win/nsIconChannel.cpp
+++ b/modules/libpr0n/decoders/icon/win/nsIconChannel.cpp
@@ -95,17 +95,17 @@ NS_IMPL_THREADSAFE_ISUPPORTS4(nsIconChan
                               nsIRequest,
                               nsIRequestObserver,
                               nsIStreamListener)
 
 nsresult nsIconChannel::Init(nsIURI* uri)
 {
   NS_ASSERTION(uri, "no uri");
   mUrl = uri;
-
+  mOriginalURI = uri;
   nsresult rv;
   mPump = do_CreateInstance(NS_INPUTSTREAMPUMP_CONTRACTID, &rv);
   return rv;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsIRequest methods:
 
@@ -161,23 +161,24 @@ NS_IMETHODIMP nsIconChannel::SetLoadFlag
   return mPump->SetLoadFlags(aLoadAttributes);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsIChannel methods:
 
 NS_IMETHODIMP nsIconChannel::GetOriginalURI(nsIURI* *aURI)
 {
-  *aURI = mOriginalURI ? mOriginalURI : mUrl;
+  *aURI = mOriginalURI;
   NS_ADDREF(*aURI);
   return NS_OK;
 }
 
 NS_IMETHODIMP nsIconChannel::SetOriginalURI(nsIURI* aURI)
 {
+  NS_ENSURE_ARG_POINTER(aURI);
   mOriginalURI = aURI;
   return NS_OK;
 }
 
 NS_IMETHODIMP nsIconChannel::GetURI(nsIURI* *aURI)
 {
   *aURI = mUrl;
   NS_IF_ADDREF(*aURI);
--- a/netwerk/base/public/nsIChannel.idl
+++ b/netwerk/base/public/nsIChannel.idl
@@ -55,19 +55,21 @@ interface nsIStreamListener;
  * response headers to be retrieved for the corresponding http transaction. 
  *
  * @status FROZEN
  */
 [scriptable, uuid(c63a055a-a676-4e71-bf3c-6cfa11082018)]
 interface nsIChannel : nsIRequest
 {
     /**
-     * The original URI used to construct the channel. This is used in the case
-     * of a redirect or URI "resolution" (e.g. resolving a resource: URI to a
-     * file: URI) so that the original pre-redirect URI can still be obtained. 
+     * The original URI used to construct the channel. This is used in
+     * the case of a redirect or URI "resolution" (e.g. resolving a
+     * resource: URI to a file: URI) so that the original pre-redirect
+     * URI can still be obtained.  This is never null.  Attempts to
+     * set it to null must throw.
      *
      * NOTE: this is distinctly different from the http Referer (referring URI),
      * which is typically the page that contained the original URI (accessible
      * from nsIHttpChannel).
      */
     attribute nsIURI originalURI;
 
     /**
--- a/netwerk/base/src/nsBaseChannel.cpp
+++ b/netwerk/base/src/nsBaseChannel.cpp
@@ -370,23 +370,24 @@ nsBaseChannel::SetLoadGroup(nsILoadGroup
 
 //-----------------------------------------------------------------------------
 // nsBaseChannel::nsIChannel
 
 NS_IMETHODIMP
 nsBaseChannel::GetOriginalURI(nsIURI **aURI)
 {
   *aURI = OriginalURI();
-  NS_IF_ADDREF(*aURI);
+  NS_ADDREF(*aURI);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsBaseChannel::SetOriginalURI(nsIURI *aURI)
 {
+  NS_ENSURE_ARG_POINTER(aURI);
   mOriginalURI = aURI;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsBaseChannel::GetURI(nsIURI **aURI)
 {
   NS_IF_ADDREF(*aURI = mURI);
--- a/netwerk/base/src/nsBaseChannel.h
+++ b/netwerk/base/src/nsBaseChannel.h
@@ -150,20 +150,22 @@ public:
   // The URI member should be initialized before the channel is used, and then
   // it should never be changed again until the channel is destroyed.
   nsIURI *URI() {
     return mURI;
   }
   void SetURI(nsIURI *uri) {
     NS_ASSERTION(uri, "must specify a non-null URI");
     NS_ASSERTION(!mURI, "must not modify URI");
+    NS_ASSERTION(!mOriginalURI, "how did that get set so early?");
     mURI = uri;
+    mOriginalURI = uri;
   }
   nsIURI *OriginalURI() {
-    return mOriginalURI ? mOriginalURI : mURI;
+    return mOriginalURI;
   }
 
   // The security info is a property of the transport-layer, which should be
   // assigned by the subclass.
   nsISupports *SecurityInfo() {
     return mSecurityInfo; 
   }
   void SetSecurityInfo(nsISupports *info) {
--- a/netwerk/protocol/http/src/nsHttpChannel.cpp
+++ b/netwerk/protocol/http/src/nsHttpChannel.cpp
@@ -3811,22 +3811,23 @@ nsHttpChannel::SetLoadFlags(nsLoadFlags 
 // nsHttpChannel::nsIChannel
 //-----------------------------------------------------------------------------
 
 NS_IMETHODIMP
 nsHttpChannel::GetOriginalURI(nsIURI **originalURI)
 {
     NS_ENSURE_ARG_POINTER(originalURI);
     *originalURI = mOriginalURI;
-    NS_IF_ADDREF(*originalURI);
+    NS_ADDREF(*originalURI);
     return NS_OK;
 }
 NS_IMETHODIMP
 nsHttpChannel::SetOriginalURI(nsIURI *originalURI)
 {
+    NS_ENSURE_ARG_POINTER(originalURI);
     mOriginalURI = originalURI;
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsHttpChannel::GetURI(nsIURI **URI)
 {
     NS_ENSURE_ARG_POINTER(URI);
--- a/netwerk/protocol/viewsource/src/nsViewSourceChannel.cpp
+++ b/netwerk/protocol/viewsource/src/nsViewSourceChannel.cpp
@@ -155,23 +155,24 @@ nsViewSourceChannel::Resume(void)
 ////////////////////////////////////////////////////////////////////////////////
 // nsIChannel methods:
 
 NS_IMETHODIMP
 nsViewSourceChannel::GetOriginalURI(nsIURI* *aURI)
 {
     NS_ASSERTION(aURI, "Null out param!");
     *aURI = mOriginalURI;
-    NS_IF_ADDREF(*aURI);
+    NS_ADDREF(*aURI);
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsViewSourceChannel::SetOriginalURI(nsIURI* aURI)
 {
+    NS_ENSURE_ARG_POINTER(aURI);
     mOriginalURI = aURI;
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsViewSourceChannel::GetURI(nsIURI* *aURI)
 {
     NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
--- a/uriloader/exthandler/nsExternalProtocolHandler.cpp
+++ b/uriloader/exthandler/nsExternalProtocolHandler.cpp
@@ -135,17 +135,17 @@ NS_IMETHODIMP
 nsExtProtocolChannel::GetSecurityInfo(nsISupports * *aSecurityInfo)
 {
   *aSecurityInfo = nsnull;
   return NS_OK;
 }
 
 NS_IMETHODIMP nsExtProtocolChannel::GetOriginalURI(nsIURI* *aURI)
 {
-  NS_IF_ADDREF(*aURI = mOriginalURI);
+  NS_ADDREF(*aURI = mOriginalURI);
   return NS_OK; 
 }
  
 NS_IMETHODIMP nsExtProtocolChannel::SetOriginalURI(nsIURI* aURI)
 {
   NS_ENSURE_ARG_POINTER(aURI);
   mOriginalURI = aURI;
   return NS_OK;