Bug 1442242 - Make the constuctors of URI implementations private r=mayhemer
☠☠ backed out by daef726185bb ☠ ☠
authorValentin Gosu <valentin.gosu@gmail.com>
Tue, 20 Mar 2018 12:52:50 +0100
changeset 409003 9f37df3c62e1c821d646cde969a278357741ba2b
parent 409002 65b8727bfe7632fda2aa8f2652529d24e722d1df
child 409004 c37ee39efce7a318de366e9c2736ca4951e091cd
push id33671
push usercsabou@mozilla.com
push dateTue, 20 Mar 2018 22:23:32 +0000
treeherdermozilla-central@e2e874ceae78 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmayhemer
bugs1442242
milestone61.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1442242 - Make the constuctors of URI implementations private r=mayhemer MozReview-Commit-ID: 4oo66aYg66s
dom/file/nsHostObjectURI.h
dom/jsurl/nsJSProtocolHandler.cpp
dom/jsurl/nsJSProtocolHandler.h
image/decoders/icon/nsIconModule.cpp
image/decoders/icon/nsIconURI.h
netwerk/base/nsINestedURI.idl
netwerk/base/nsSimpleNestedURI.cpp
netwerk/base/nsSimpleNestedURI.h
netwerk/base/nsSimpleURI.h
netwerk/base/nsStandardURL.h
netwerk/build/nsNetCID.h
netwerk/protocol/about/nsAboutProtocolHandler.cpp
netwerk/protocol/about/nsAboutProtocolHandler.h
netwerk/protocol/res/SubstitutingProtocolHandler.h
netwerk/protocol/viewsource/nsViewSourceHandler.cpp
--- a/dom/file/nsHostObjectURI.h
+++ b/dom/file/nsHostObjectURI.h
@@ -26,27 +26,28 @@
  * "mediasource".
  */
 class nsHostObjectURI final
   : public mozilla::net::nsSimpleURI
   , public nsIURIWithPrincipal
   , public nsIURIWithBlobImpl
   , public nsSupportsWeakReference
 {
-public:
+private:
   nsHostObjectURI(nsIPrincipal* aPrincipal,
                   mozilla::dom::BlobImpl* aBlobImpl)
     : mozilla::net::nsSimpleURI()
     , mPrincipal(aPrincipal)
     , mBlobImpl(aBlobImpl)
   {}
 
   // For use only from deserialization
   nsHostObjectURI() : mozilla::net::nsSimpleURI() {}
 
+public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIURIWITHBLOBIMPL
   NS_DECL_NSIURIWITHPRINCIPAL
   NS_DECL_NSISERIALIZABLE
   NS_DECL_NSICLASSINFO
   NS_DECL_NSIIPCSERIALIZABLEURI
 
   // Override CloneInternal() and EqualsInternal()
--- a/dom/jsurl/nsJSProtocolHandler.cpp
+++ b/dom/jsurl/nsJSProtocolHandler.cpp
@@ -1186,38 +1186,41 @@ nsJSProtocolHandler::GetProtocolFlags(ui
 }
 
 NS_IMETHODIMP
 nsJSProtocolHandler::NewURI(const nsACString &aSpec,
                             const char *aCharset,
                             nsIURI *aBaseURI,
                             nsIURI **result)
 {
-    nsresult rv;
+    nsresult rv = NS_OK;
 
     // javascript: URLs (currently) have no additional structure beyond that
     // provided by standard URLs, so there is no "outer" object given to
     // CreateInstance.
 
-    nsCOMPtr<nsIURI> url = new nsJSURI(aBaseURI);
-    NS_MutateURI mutator(url);
+    NS_MutateURI mutator(new nsJSURI::Mutator());
+    nsCOMPtr<nsIURI> base(aBaseURI);
+    mutator.Apply(NS_MutatorMethod(&nsIJSURIMutator::SetBase, base));
     if (!aCharset || !nsCRT::strcasecmp("UTF-8", aCharset)) {
-      mutator.SetSpec(aSpec);
+        mutator.SetSpec(aSpec);
     } else {
-      nsAutoCString utf8Spec;
-      rv = EnsureUTF8Spec(PromiseFlatCString(aSpec), aCharset, utf8Spec);
-      if (NS_SUCCEEDED(rv)) {
+        nsAutoCString utf8Spec;
+        rv = EnsureUTF8Spec(PromiseFlatCString(aSpec), aCharset, utf8Spec);
+        if (NS_FAILED(rv)) {
+            return rv;
+        }
         if (utf8Spec.IsEmpty()) {
-          mutator.SetSpec(aSpec);
+            mutator.SetSpec(aSpec);
         } else {
-          mutator.SetSpec(utf8Spec);
+            mutator.SetSpec(utf8Spec);
         }
-      }
     }
 
+    nsCOMPtr<nsIURI> url;
     rv = mutator.Finalize(url);
     if (NS_FAILED(rv)) {
         return rv;
     }
 
     url.forget(result);
     return rv;
 }
@@ -1386,17 +1389,18 @@ nsJSURI::StartClone(mozilla::net::nsSimp
     SetRefOnClone(url, refHandlingMode, newRef);
     return url;
 }
 
 // Queries this list of interfaces. If none match, it queries mURI.
 NS_IMPL_NSIURIMUTATOR_ISUPPORTS(nsJSURI::Mutator,
                                 nsIURISetters,
                                 nsIURIMutator,
-                                nsISerializable)
+                                nsISerializable,
+                                nsIJSURIMutator)
 
 NS_IMETHODIMP
 nsJSURI::Mutate(nsIURIMutator** aMutator)
 {
     RefPtr<nsJSURI::Mutator> mutator = new nsJSURI::Mutator();
     nsresult rv = mutator->InitFromURI(this);
     if (NS_FAILED(rv)) {
         return rv;
--- a/dom/jsurl/nsJSProtocolHandler.h
+++ b/dom/jsurl/nsJSProtocolHandler.h
@@ -9,16 +9,17 @@
 #include "mozilla/Attributes.h"
 #include "nsIProtocolHandler.h"
 #include "nsITextToSubURI.h"
 #include "nsIURI.h"
 #include "nsIMutable.h"
 #include "nsISerializable.h"
 #include "nsIClassInfo.h"
 #include "nsSimpleURI.h"
+#include "nsINestedURI.h"
 
 #define NS_JSPROTOCOLHANDLER_CID                     \
 { /* bfc310d2-38a0-11d3-8cd3-0060b0fc14a3 */         \
     0xbfc310d2,                                      \
     0x38a0,                                          \
     0x11d3,                                          \
     {0x8c, 0xd3, 0x00, 0x60, 0xb0, 0xfc, 0x14, 0xa3} \
 }
@@ -63,28 +64,23 @@ protected:
     virtual ~nsJSProtocolHandler();
 
     nsresult EnsureUTF8Spec(const nsCString& aSpec, const char *aCharset,
                             nsACString &aUTF8Spec);
 
     nsCOMPtr<nsITextToSubURI>  mTextToSubURI;
 };
 
-
 class nsJSURI final
     : public mozilla::net::nsSimpleURI
 {
 public:
     using mozilla::net::nsSimpleURI::Read;
     using mozilla::net::nsSimpleURI::Write;
 
-    nsJSURI() {}
-
-    explicit nsJSURI(nsIURI* aBaseURI) : mBaseURI(aBaseURI) {}
-
     nsIURI* GetBaseURI() const
     {
         return mBaseURI;
     }
 
     NS_DECL_ISUPPORTS_INHERITED
 
     // nsIURI overrides
@@ -100,32 +96,36 @@ public:
     NS_DECL_NSIIPCSERIALIZABLEURI
 
     // Override the nsIClassInfo method GetClassIDNoAlloc to make sure our
     // nsISerializable impl works right.
     NS_IMETHOD GetClassIDNoAlloc(nsCID *aClassIDNoAlloc) override;
     //NS_IMETHOD QueryInterface( const nsIID& aIID, void** aInstancePtr ) override;
 
 protected:
+    nsJSURI() {}
+    explicit nsJSURI(nsIURI* aBaseURI) : mBaseURI(aBaseURI) {}
+
     virtual ~nsJSURI() {}
 
     virtual nsresult EqualsInternal(nsIURI* other,
                                     RefHandlingEnum refHandlingMode,
                                     bool* result) override;
     bool Deserialize(const mozilla::ipc::URIParams&);
     nsresult ReadPrivate(nsIObjectInputStream *aStream);
 
 private:
     nsCOMPtr<nsIURI> mBaseURI;
 
 public:
     class Mutator final
         : public nsIURIMutator
         , public BaseURIMutator<nsJSURI>
         , public nsISerializable
+        , public nsIJSURIMutator
     {
         NS_DECL_ISUPPORTS
         NS_FORWARD_SAFE_NSIURISETTERS_RET(mURI)
         NS_DEFINE_NSIMUTATOR_COMMON
 
         NS_IMETHOD
         Write(nsIObjectOutputStream *aOutputStream) override
         {
@@ -133,16 +133,23 @@ public:
         }
 
         MOZ_MUST_USE NS_IMETHOD
         Read(nsIObjectInputStream* aStream) override
         {
             return InitFromInputStream(aStream);
         }
 
+        MOZ_MUST_USE NS_IMETHOD
+        SetBase(nsIURI* aBaseURI) override
+        {
+            mURI = new nsJSURI(aBaseURI);
+            return NS_OK;
+        }
+
         explicit Mutator() { }
     private:
         virtual ~Mutator() { }
 
         friend class nsJSURI;
     };
 
     friend BaseURIMutator<nsJSURI>;
--- a/image/decoders/icon/nsIconModule.cpp
+++ b/image/decoders/icon/nsIconModule.cpp
@@ -14,27 +14,24 @@
 // objects that just require generic constructors
 //*****************************************************************************
 // Protocol CIDs
 
 #define NS_ICONPROTOCOL_CID { 0xd0f9db12, 0x249c, 0x11d5, \
                               { 0x99, 0x5, 0x0, 0x10, 0x83, 0x1, 0xe, 0x9b } }
 
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsIconProtocolHandler)
-NS_GENERIC_FACTORY_CONSTRUCTOR(nsMozIconURI)
 typedef nsMozIconURI::Mutator nsMozIconURIMutator;
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsMozIconURIMutator)
 
 NS_DEFINE_NAMED_CID(NS_ICONPROTOCOL_CID);
-NS_DEFINE_NAMED_CID(NS_MOZICONURI_CID);
 NS_DEFINE_NAMED_CID(NS_MOZICONURIMUTATOR_CID);
 
 static const mozilla::Module::CIDEntry kIconCIDs[] = {
   { &kNS_ICONPROTOCOL_CID, false, nullptr, nsIconProtocolHandlerConstructor },
-  { &kNS_MOZICONURI_CID, false, nullptr, nsMozIconURIConstructor },
   { &kNS_MOZICONURIMUTATOR_CID, false, nullptr, nsMozIconURIMutatorConstructor },
   { nullptr }
 };
 
 static const mozilla::Module::ContractIDEntry kIconContracts[] = {
   { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "moz-icon", &kNS_ICONPROTOCOL_CID },
   { nullptr }
 };
--- a/image/decoders/icon/nsIconURI.h
+++ b/image/decoders/icon/nsIconURI.h
@@ -25,20 +25,18 @@ class nsMozIconURI final
 {
 public:
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_NSIURI
   NS_DECL_NSIMOZICONURI
   NS_DECL_NSIIPCSERIALIZABLEURI
   NS_DECL_NSINESTEDURI
 
-  // nsMozIconURI
+protected:
   nsMozIconURI();
-
-protected:
   virtual ~nsMozIconURI();
   nsCOMPtr<nsIURL> mIconURL; // a URL that we want the icon for
   uint32_t mSize; // the # of pixels in a row that we want for this image.
                   // Typically 16, 32, 128, etc.
   nsCString mContentType; // optional field explicitly specifying the content
                           // type
   nsCString mFileName; // for if we don't have an actual file path, we're just
                        // given a filename with an extension
--- a/netwerk/base/nsINestedURI.idl
+++ b/netwerk/base/nsINestedURI.idl
@@ -39,8 +39,37 @@ interface nsINestedURI : nsISupports
    * getter succeeds.  This is equivalent to repeatedly calling innerURI while
    * the returned URI QIs to nsINestedURI.
    *
    * Modifying the returned URI must not in any way modify the nested URI; this
    * means the returned URI must be either immutable or a clone.   
    */
   readonly attribute nsIURI innermostURI;
 };
+
+[scriptable, builtinclass, uuid(ca3d6c03-4eee-4271-a97a-d16c0a0b2c5c)]
+interface nsINestedURIMutator : nsISupports
+{
+  /*
+   *  - Creates a new URI with the given innerURI.
+   */
+  [must_use, noscript] void init(in nsIURI innerURI);
+};
+
+[scriptable, builtinclass, uuid(c6357a3b-c2bb-4b4b-9278-513377398a38)]
+interface nsINestedAboutURIMutator : nsISupports
+{
+  /*
+   *  - Creates a new URI with the given innerURI and base.
+   */
+  [must_use, noscript] void initWithBase(in nsIURI innerURI, in nsIURI baseURI);
+};
+
+[scriptable, builtinclass, uuid(3bd44535-08ea-478f-99b9-85fa1084e820)]
+interface nsIJSURIMutator : nsISupports
+{
+  /*
+   *  - Inits the URI by setting the base URI
+   *  - It is the caller's responsibility to also call SetSpec afterwards,
+   *    otherwise we will return an incomplete URI (with only a base)
+   */
+  [must_use, noscript] void setBase(in nsIURI aBaseURI);
+};
--- a/netwerk/base/nsSimpleNestedURI.cpp
+++ b/netwerk/base/nsSimpleNestedURI.cpp
@@ -192,17 +192,18 @@ nsSimpleNestedURI::GetClassIDNoAlloc(nsC
     *aClassIDNoAlloc = kSimpleNestedURICID;
     return NS_OK;
 }
 
 // Queries this list of interfaces. If none match, it queries mURI.
 NS_IMPL_NSIURIMUTATOR_ISUPPORTS(nsSimpleNestedURI::Mutator,
                                 nsIURISetters,
                                 nsIURIMutator,
-                                nsISerializable)
+                                nsISerializable,
+                                nsINestedURIMutator)
 
 NS_IMETHODIMP
 nsSimpleNestedURI::Mutate(nsIURIMutator** aMutator)
 {
     RefPtr<nsSimpleNestedURI::Mutator> mutator = new nsSimpleNestedURI::Mutator();
     nsresult rv = mutator->InitFromURI(this);
     if (NS_FAILED(rv)) {
         return rv;
--- a/netwerk/base/nsSimpleNestedURI.h
+++ b/netwerk/base/nsSimpleNestedURI.h
@@ -25,29 +25,21 @@
 
 namespace mozilla {
 namespace net {
 
 class nsSimpleNestedURI : public nsSimpleURI,
                           public nsINestedURI
 {
 protected:
-    ~nsSimpleNestedURI() {}
-
-public:
-    // To be used by deserialization only.  Leaves this object in an
-    // uninitialized state that will throw on most accesses.
-    nsSimpleNestedURI()
-    {
-    }
-
-    // Constructor that should generally be used when constructing an object of
-    // this class with |operator new|.
+    nsSimpleNestedURI() = default;
     explicit nsSimpleNestedURI(nsIURI* innerURI);
 
+    ~nsSimpleNestedURI() = default;
+public:
     NS_DECL_ISUPPORTS_INHERITED
     NS_DECL_NSINESTEDURI
 
     // Overrides for various methods nsSimpleURI implements follow.
 
     // nsSimpleURI overrides
     virtual nsresult EqualsInternal(nsIURI* other,
                                     RefHandlingEnum refHandlingMode,
@@ -73,16 +65,17 @@ protected:
     bool Deserialize(const mozilla::ipc::URIParams&);
     nsresult ReadPrivate(nsIObjectInputStream *stream);
 
 public:
     class Mutator final
         : public nsIURIMutator
         , public BaseURIMutator<nsSimpleNestedURI>
         , public nsISerializable
+        , public nsINestedURIMutator
     {
         NS_DECL_ISUPPORTS
         NS_FORWARD_SAFE_NSIURISETTERS_RET(mURI)
 
         explicit Mutator() { }
     private:
         virtual ~Mutator() { }
 
@@ -116,16 +109,23 @@ public:
         SetSpec(const nsACString& aSpec, nsIURIMutator** aMutator) override
         {
             if (aMutator) {
                 NS_ADDREF(*aMutator = this);
             }
             return InitFromSpec(aSpec);
         }
 
+        MOZ_MUST_USE NS_IMETHOD
+        Init(nsIURI* innerURI) override
+        {
+            mURI = new nsSimpleNestedURI(innerURI);
+            return NS_OK;
+        }
+
         void ResetMutable()
         {
             if (mURI) {
                 mURI->mMutable = true;
             }
         }
 
         friend class nsSimpleNestedURI;
--- a/netwerk/base/nsSimpleURI.h
+++ b/netwerk/base/nsSimpleURI.h
@@ -31,32 +31,31 @@ class nsSimpleURI
     : public nsIURI
     , public nsISerializable
     , public nsIClassInfo
     , public nsIMutable
     , public nsISizeOf
     , public nsIIPCSerializableURI
 {
 protected:
+    nsSimpleURI();
     virtual ~nsSimpleURI();
 
 public:
     NS_DECL_ISUPPORTS
     NS_DECL_NSIURI
     NS_DECL_NSISERIALIZABLE
     NS_DECL_NSICLASSINFO
     NS_DECL_NSIMUTABLE
     NS_DECL_NSIIPCSERIALIZABLEURI
 
     static already_AddRefed<nsSimpleURI> From(nsIURI* aURI);
 
     // nsSimpleURI methods:
 
-    nsSimpleURI();
-
     bool Equals(nsSimpleURI* aOther)
     {
       return EqualsInternal(aOther, eHonorRef);
     }
 
     // nsISizeOf
     // Among the sub-classes that inherit (directly or indirectly) from
     // nsSimpleURI, measurement of the following members may be added later if
--- a/netwerk/base/nsStandardURL.h
+++ b/netwerk/base/nsStandardURL.h
@@ -50,16 +50,17 @@ class nsStandardURL : public nsIFileURL
                     , public nsIIPCSerializableURI
                     , public nsISensitiveInfoHiddenURI
 #ifdef DEBUG_DUMP_URLS_AT_SHUTDOWN
                     , public LinkedListElement<nsStandardURL>
 #endif
 {
 protected:
     virtual ~nsStandardURL();
+    explicit nsStandardURL(bool aSupportsFileURL = false, bool aTrackURL = true);
 
 public:
     NS_DECL_ISUPPORTS
     NS_DECL_NSIURI
     NS_DECL_NSIURL
     NS_DECL_NSIFILEURL
     NS_DECL_NSISTANDARDURL
     NS_DECL_NSISERIALIZABLE
@@ -67,18 +68,16 @@ public:
     NS_DECL_NSIMUTABLE
     NS_DECL_NSIIPCSERIALIZABLEURI
     NS_DECL_NSISENSITIVEINFOHIDDENURI
 
     // nsISizeOf
     virtual size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override;
     virtual size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override;
 
-    explicit nsStandardURL(bool aSupportsFileURL = false, bool aTrackURL = true);
-
     static void InitGlobalObjects();
     static void ShutdownGlobalObjects();
 
 public: /* internal -- HPUX compiler can't handle this being private */
     //
     // location and length of an url segment relative to mSpec
     //
     struct URLSegment
--- a/netwerk/build/nsNetCID.h
+++ b/netwerk/build/nsNetCID.h
@@ -66,18 +66,16 @@
 { /* e1c61582-2a84-11d3-8cce-0060b0fc14a3 */         \
     0xe1c61582,                                      \
     0x2a84,                                          \
     0x11d3,                                          \
     {0x8c, 0xce, 0x00, 0x60, 0xb0, 0xfc, 0x14, 0xa3} \
 }
 
 // component implementing nsIURI, nsISerializable, and nsIClassInfo.
-#define NS_SIMPLEURI_CONTRACTID \
-    "@mozilla.org/network/simple-uri;1"
 #define NS_SIMPLEURI_CID                              \
 { /* e0da1d70-2f7b-11d3-8cd0-0060b0fc14a3 */          \
      0xe0da1d70,                                      \
      0x2f7b,                                          \
      0x11d3,                                          \
      {0x8c, 0xd0, 0x00, 0x60, 0xb0, 0xfc, 0x14, 0xa3} \
 }
 
@@ -124,18 +122,16 @@
      0xb0054ef3,                                         \
      0xb096,                                             \
      0x483d,                                             \
      { 0x82, 0x42, 0x4e, 0xe3, 0x6b, 0x7b, 0x21, 0x15 }  \
 }
 
 // component implementing nsIStandardURL, nsIURI, nsIURL, nsISerializable,
 // and nsIClassInfo.
-#define NS_STANDARDURL_CONTRACTID \
-    "@mozilla.org/network/standard-url;1"
 #define NS_STANDARDURL_CID                           \
 { /* de9472d0-8034-11d3-9399-00104ba0fd40 */         \
     0xde9472d0,                                      \
     0x8034,                                          \
     0x11d3,                                          \
     {0x93, 0x99, 0x00, 0x10, 0x4b, 0xa0, 0xfd, 0x40} \
 }
 
--- a/netwerk/protocol/about/nsAboutProtocolHandler.cpp
+++ b/netwerk/protocol/about/nsAboutProtocolHandler.cpp
@@ -146,18 +146,20 @@ nsAboutProtocolHandler::NewURI(const nsA
         NS_ENSURE_SUCCESS(rv, rv);
 
         spec.InsertLiteral("moz-safe-about:", 0);
 
         nsCOMPtr<nsIURI> inner;
         rv = NS_NewURI(getter_AddRefs(inner), spec);
         NS_ENSURE_SUCCESS(rv, rv);
 
-        RefPtr<nsSimpleNestedURI> outer = new nsNestedAboutURI(inner, aBaseURI);
-        rv = NS_MutateURI(outer)
+        nsCOMPtr<nsIURI> base(aBaseURI);
+        rv = NS_MutateURI(new nsNestedAboutURI::Mutator())
+               .Apply(NS_MutatorMethod(&nsINestedAboutURIMutator::InitWithBase,
+                                       inner, base))
                .SetSpec(aSpec)
                .Finalize(url);
         NS_ENSURE_SUCCESS(rv, rv);
     }
 
     // We don't want to allow mutation, since it would allow safe and
     // unsafe URIs to change into each other...
     NS_TryToSetImmutable(url);
@@ -446,17 +448,18 @@ nsNestedAboutURI::StartClone(nsSimpleURI
 
     return url;
 }
 
 // Queries this list of interfaces. If none match, it queries mURI.
 NS_IMPL_NSIURIMUTATOR_ISUPPORTS(nsNestedAboutURI::Mutator,
                                 nsIURISetters,
                                 nsIURIMutator,
-                                nsISerializable)
+                                nsISerializable,
+                                nsINestedAboutURIMutator)
 
 NS_IMETHODIMP
 nsNestedAboutURI::Mutate(nsIURIMutator** aMutator)
 {
     RefPtr<nsNestedAboutURI::Mutator> mutator = new nsNestedAboutURI::Mutator();
     nsresult rv = mutator->InitFromURI(this);
     if (NS_FAILED(rv)) {
         return rv;
--- a/netwerk/protocol/about/nsAboutProtocolHandler.h
+++ b/netwerk/protocol/about/nsAboutProtocolHandler.h
@@ -51,27 +51,25 @@ private:
     ~nsSafeAboutProtocolHandler() {}
 };
 
 
 // Class to allow us to propagate the base URI to about:blank correctly
 class nsNestedAboutURI final
     : public nsSimpleNestedURI
 {
-public:
+private:
     nsNestedAboutURI(nsIURI* aInnerURI, nsIURI* aBaseURI)
         : nsSimpleNestedURI(aInnerURI)
         , mBaseURI(aBaseURI)
     {}
-
-    // For use only from deserialization
     nsNestedAboutURI() : nsSimpleNestedURI() {}
-
     virtual ~nsNestedAboutURI() {}
 
+public:
     // Override QI so we can QI to our CID as needed
     NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr) override;
 
     // Override StartClone(), the nsISerializable methods, and
     // GetClassIDNoAlloc; this last is needed to make our nsISerializable impl
     // work right.
     virtual nsSimpleURI* StartClone(RefHandlingEnum aRefHandlingMode,
                                     const nsACString& newRef) override;
@@ -89,16 +87,17 @@ protected:
     nsCOMPtr<nsIURI> mBaseURI;
     nsresult ReadPrivate(nsIObjectInputStream *stream);
 
 public:
     class Mutator final
         : public nsIURIMutator
         , public BaseURIMutator<nsNestedAboutURI>
         , public nsISerializable
+        , public nsINestedAboutURIMutator
     {
         NS_DECL_ISUPPORTS
         NS_FORWARD_SAFE_NSIURISETTERS_RET(mURI)
 
         explicit Mutator() { }
     private:
         virtual ~Mutator() { }
 
@@ -132,16 +131,23 @@ public:
         SetSpec(const nsACString& aSpec, nsIURIMutator** aMutator) override
         {
             if (aMutator) {
                 NS_ADDREF(*aMutator = this);
             }
             return InitFromSpec(aSpec);
         }
 
+        MOZ_MUST_USE NS_IMETHOD
+        InitWithBase(nsIURI* aInnerURI, nsIURI* aBaseURI) override
+        {
+            mURI = new nsNestedAboutURI(aInnerURI, aBaseURI);
+            return NS_OK;
+        }
+
         void ResetMutable()
         {
             if (mURI) {
                 mURI->mMutable = true;
             }
         }
 
         friend class nsNestedAboutURI;
--- a/netwerk/protocol/res/SubstitutingProtocolHandler.h
+++ b/netwerk/protocol/res/SubstitutingProtocolHandler.h
@@ -117,22 +117,25 @@ private:
   // we just try to enforce it on new protocols going forward.
   bool mEnforceFileOrJar;
 };
 
 // SubstitutingURL : overrides nsStandardURL::GetFile to provide nsIFile resolution
 class SubstitutingURL : public nsStandardURL
 {
 public:
-  explicit SubstitutingURL() : nsStandardURL(true) {}
-  explicit SubstitutingURL(bool aSupportsFileURL) : nsStandardURL(true) { MOZ_ASSERT(aSupportsFileURL); }
   virtual nsStandardURL* StartClone() override;
   virtual MOZ_MUST_USE nsresult EnsureFile() override;
   NS_IMETHOD GetClassIDNoAlloc(nsCID *aCID) override;
 
+private:
+  explicit SubstitutingURL() : nsStandardURL(true) {}
+  explicit SubstitutingURL(bool aSupportsFileURL) : nsStandardURL(true) { MOZ_ASSERT(aSupportsFileURL); }
+
+public:
   class Mutator
     : public TemplatedMutator<SubstitutingURL>
   {
     NS_DECL_ISUPPORTS
   public:
     explicit Mutator() = default;
   private:
     virtual ~Mutator() = default;
@@ -150,14 +153,15 @@ public:
     if (NS_FAILED(rv)) {
       return rv;
     }
     mutator.forget(aMutator);
     return NS_OK;
   }
 
   friend BaseURIMutator<SubstitutingURL>;
+  friend TemplatedMutator<SubstitutingURL>;
 };
 
 } // namespace net
 } // namespace mozilla
 
 #endif /* SubstitutingProtocolHandler_h___ */
--- a/netwerk/protocol/viewsource/nsViewSourceHandler.cpp
+++ b/netwerk/protocol/viewsource/nsViewSourceHandler.cpp
@@ -91,22 +91,19 @@ nsViewSourceHandler::NewURI(const nsACSt
     rv = innerURI->GetAsciiSpec(asciiSpec);
     if (NS_FAILED(rv))
         return rv;
 
     // put back our scheme and construct a simple-uri wrapper
 
     asciiSpec.Insert(VIEW_SOURCE ":", 0);
 
-    // We can't swap() from an RefPtr<nsSimpleNestedURI> to an nsIURI**,
-    // sadly.
-    RefPtr<nsSimpleNestedURI> ourURI = new nsSimpleNestedURI(innerURI);
-
     nsCOMPtr<nsIURI> uri;
-    rv = NS_MutateURI(ourURI)
+    rv = NS_MutateURI(new nsSimpleNestedURI::Mutator())
+           .Apply(NS_MutatorMethod(&nsINestedURIMutator::Init, innerURI))
            .SetSpec(asciiSpec)
            .Finalize(uri);
     if (NS_FAILED(rv)) {
         return rv;
     }
 
     // Make the URI immutable so it's impossible to get it out of sync
     // with its inner URI.