Bug 1448058 - Remove nsIMutable from URI implementations draft
authorValentin Gosu <valentin.gosu@gmail.com>
Wed, 09 May 2018 18:21:24 +0200
changeset 793161 8da735083f41e773336cdc505298d5502b857082
parent 793056 9294f67b3f3bd4a3dd898961148cecd8bfc1ce9c
child 793918 51b5c6d422344cdbc129f46ec8b03203f88637fb
push id109302
push uservalentin.gosu@gmail.com
push dateWed, 09 May 2018 16:22:43 +0000
bugs1448058
milestone62.0a1
Bug 1448058 - Remove nsIMutable from URI implementations * Also removes NS_TryToMakeImmutable, NS_TryToSetImmutable, URIIsImmutable * NS_EnsureSafeToReturn, nsINetUtil.toImmutableURI MozReview-Commit-ID: 5eFtFm2CQt7
caps/ContentPrincipal.cpp
caps/ContentPrincipal.h
caps/NullPrincipal.cpp
chrome/nsChromeProtocolHandler.cpp
docshell/base/nsDocShell.cpp
dom/base/nsContentUtils.cpp
dom/base/nsDocument.cpp
dom/base/nsImageLoadingContent.cpp
dom/base/nsObjectLoadingContent.cpp
dom/html/nsHTMLDocument.cpp
ipc/glue/URIParams.ipdlh
modules/libjar/nsJARURI.cpp
netwerk/base/nsINetUtil.idl
netwerk/base/nsIOService.cpp
netwerk/base/nsIStandardURL.idl
netwerk/base/nsNetUtil.cpp
netwerk/base/nsNetUtil.h
netwerk/base/nsSimpleNestedURI.cpp
netwerk/base/nsSimpleNestedURI.h
netwerk/base/nsSimpleURI.cpp
netwerk/base/nsSimpleURI.h
netwerk/base/nsStandardURL.cpp
netwerk/base/nsStandardURL.h
netwerk/protocol/about/nsAboutProtocolHandler.cpp
netwerk/protocol/viewsource/nsViewSourceHandler.cpp
netwerk/test/unit/test_1351443-missing-NewChannel2.js
netwerk/test/unit/test_bug894586.js
--- a/caps/ContentPrincipal.cpp
+++ b/caps/ContentPrincipal.cpp
@@ -31,26 +31,16 @@
 #include "mozilla/dom/ScriptSettings.h"
 #include "mozilla/ClearOnShutdown.h"
 #include "mozilla/ExtensionPolicyService.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/HashFunctions.h"
 
 using namespace mozilla;
 
-static bool URIIsImmutable(nsIURI* aURI)
-{
-  nsCOMPtr<nsIMutable> mutableObj(do_QueryInterface(aURI));
-  bool isMutable;
-  return
-    mutableObj &&
-    NS_SUCCEEDED(mutableObj->GetMutable(&isMutable)) &&
-    !isMutable;
-}
-
 static inline ExtensionPolicyService&
 EPS()
 {
   return ExtensionPolicyService::GetSingleton();
 }
 
 NS_IMPL_CLASSINFO(ContentPrincipal, nullptr, nsIClassInfo::MAIN_THREAD_ONLY,
                   NS_PRINCIPAL_CID)
@@ -58,18 +48,16 @@ NS_IMPL_QUERY_INTERFACE_CI(ContentPrinci
                            nsIPrincipal,
                            nsISerializable)
 NS_IMPL_CI_INTERFACE_GETTER(ContentPrincipal,
                             nsIPrincipal,
                             nsISerializable)
 
 ContentPrincipal::ContentPrincipal()
   : BasePrincipal(eCodebasePrincipal)
-  , mCodebaseImmutable(false)
-  , mDomainImmutable(false)
 {
 }
 
 ContentPrincipal::~ContentPrincipal()
 {
   // let's clear the principal within the csp to avoid a tangling pointer
   if (mCSP) {
     static_cast<nsCSPContext*>(mCSP.get())->clearLoadingPrincipal();
@@ -91,19 +79,17 @@ ContentPrincipal::Init(nsIURI *aCodebase
   bool hasFlag;
   Unused << hasFlag; // silence possible compiler warnings.
   MOZ_DIAGNOSTIC_ASSERT(
       NS_SUCCEEDED(NS_URIChainHasFlags(aCodebase,
                                        nsIProtocolHandler::URI_INHERITS_SECURITY_CONTEXT,
                                        &hasFlag)) &&
       !hasFlag);
 
-  mCodebase = NS_TryToMakeImmutable(aCodebase);
-  mCodebaseImmutable = URIIsImmutable(mCodebase);
-
+  mCodebase = aCodebase;
   FinishInit(aOriginNoSuffix, aOriginAttributes);
 
   return NS_OK;
 }
 
 nsresult
 ContentPrincipal::GetScriptLocation(nsACString &aStr)
 {
@@ -273,27 +259,18 @@ ContentPrincipal::SubsumesInternal(nsIPr
 
   // Compare codebases.
   return nsScriptSecurityManager::SecurityCompareURIs(mCodebase, otherURI);
 }
 
 NS_IMETHODIMP
 ContentPrincipal::GetURI(nsIURI** aURI)
 {
-  if (mCodebaseImmutable) {
-    NS_ADDREF(*aURI = mCodebase);
-    return NS_OK;
-  }
-
-  if (!mCodebase) {
-    *aURI = nullptr;
-    return NS_OK;
-  }
-
-  return NS_EnsureSafeToReturn(mCodebase, aURI);
+  NS_ADDREF(*aURI = mCodebase);
+  return NS_OK;
 }
 
 bool
 ContentPrincipal::MayLoadInternal(nsIURI* aURI)
 {
   // See if aURI is something like a Blob URI that is actually associated with
   // a principal.
   nsCOMPtr<nsIURIWithPrincipal> uriWithPrin = do_QueryInterface(aURI);
@@ -339,29 +316,24 @@ ContentPrincipal::GetHashValue(uint32_t*
 NS_IMETHODIMP
 ContentPrincipal::GetDomain(nsIURI** aDomain)
 {
   if (!mDomain) {
     *aDomain = nullptr;
     return NS_OK;
   }
 
-  if (mDomainImmutable) {
-    NS_ADDREF(*aDomain = mDomain);
-    return NS_OK;
-  }
-
-  return NS_EnsureSafeToReturn(mDomain, aDomain);
+  NS_ADDREF(*aDomain = mDomain);
+  return NS_OK;
 }
 
 NS_IMETHODIMP
 ContentPrincipal::SetDomain(nsIURI* aDomain)
 {
-  mDomain = NS_TryToMakeImmutable(aDomain);
-  mDomainImmutable = URIIsImmutable(mDomain);
+  mDomain = aDomain;
   SetHasExplicitDomain();
 
   // Recompute all wrappers between compartments using this principal and other
   // non-chrome compartments.
   AutoSafeJSContext cx;
   JSPrincipals *principals = nsJSPrincipals::get(static_cast<nsIPrincipal*>(this));
   bool success = js::RecomputeWrappers(cx, js::ContentCompartmentsOnly(),
                                        js::CompartmentsWithPrincipals(principals));
@@ -511,13 +483,10 @@ ContentPrincipal::Write(nsIObjectOutputS
 
   rv = NS_WriteOptionalCompoundObject(aStream, mCSP,
                                       NS_GET_IID(nsIContentSecurityPolicy),
                                       true);
   if (NS_FAILED(rv)) {
     return rv;
   }
 
-  // mCodebaseImmutable and mDomainImmutable will be recomputed based
-  // on the deserialized URIs in Read().
-
   return NS_OK;
 }
--- a/caps/ContentPrincipal.h
+++ b/caps/ContentPrincipal.h
@@ -42,19 +42,16 @@ public:
 
   static nsresult
   GenerateOriginNoSuffixFromURI(nsIURI* aURI, nsACString& aOrigin);
 
   mozilla::extensions::WebExtensionPolicy* AddonPolicy();
 
   nsCOMPtr<nsIURI> mDomain;
   nsCOMPtr<nsIURI> mCodebase;
-  // If mCodebaseImmutable is true, mCodebase is non-null and immutable
-  bool mCodebaseImmutable;
-  bool mDomainImmutable;
 
 protected:
   virtual ~ContentPrincipal();
 
   bool SubsumesInternal(nsIPrincipal* aOther,
                         DocumentDomainConsideration aConsideration) override;
   bool MayLoadInternal(nsIURI* aURI) override;
 
--- a/caps/NullPrincipal.cpp
+++ b/caps/NullPrincipal.cpp
@@ -155,23 +155,27 @@ NullPrincipal::SetCsp(nsIContentSecurity
 
   mCSP = aCsp;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 NullPrincipal::GetURI(nsIURI** aURI)
 {
-  return NS_EnsureSafeToReturn(mURI, aURI);
+  nsCOMPtr<nsIURI> uri = mURI;
+  uri.forget(aURI);
+  return NS_OK;
 }
 
 NS_IMETHODIMP
 NullPrincipal::GetDomain(nsIURI** aDomain)
 {
-  return NS_EnsureSafeToReturn(mURI, aDomain);
+  nsCOMPtr<nsIURI> uri = mURI;
+  uri.forget(aDomain);
+  return NS_OK;
 }
 
 NS_IMETHODIMP
 NullPrincipal::SetDomain(nsIURI* aDomain)
 {
   // I think the right thing to do here is to just throw...  Silently failing
   // seems counterproductive.
   return NS_ERROR_NOT_AVAILABLE;
--- a/chrome/nsChromeProtocolHandler.cpp
+++ b/chrome/nsChromeProtocolHandler.cpp
@@ -92,18 +92,16 @@ nsChromeProtocolHandler::NewURI(const ns
     // Canonify the "chrome:" URL; e.g., so that we collapse
     // "chrome://navigator/content/" and "chrome://navigator/content"
     // and "chrome://navigator/content/navigator.xul".
 
     rv = nsChromeRegistry::Canonify(surl);
     if (NS_FAILED(rv))
         return rv;
 
-    NS_TryToSetImmutable(surl);
-
     surl.forget(result);
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsChromeProtocolHandler::NewChannel2(nsIURI* aURI,
                                      nsILoadInfo* aLoadInfo,
                                      nsIChannel** aResult)
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -1425,17 +1425,17 @@ nsDocShell::SetCurrentURI(nsIURI* aURI, 
            this, aURI ? aURI->GetSpecOrDefault().get() : ""));
 
   // We don't want to send a location change when we're displaying an error
   // page, and we don't want to change our idea of "current URI" either
   if (mLoadType == LOAD_ERROR_PAGE) {
     return false;
   }
 
-  mCurrentURI = NS_TryToMakeImmutable(aURI);
+  mCurrentURI = aURI;
 
   if (!NS_IsAboutBlank(mCurrentURI)) {
     mHasLoadedNonBlankURI = true;
   }
 
   bool isRoot = false;  // Is this the root docshell
   bool isSubFrame = false;  // Is this a subframe navigation?
 
@@ -5187,21 +5187,18 @@ nsDocShell::GetDocument(nsIDOMDocument**
   return CallQueryInterface(doc, aDocument);
 }
 
 NS_IMETHODIMP
 nsDocShell::GetCurrentURI(nsIURI** aURI)
 {
   NS_ENSURE_ARG_POINTER(aURI);
 
-  if (mCurrentURI) {
-    return NS_EnsureSafeToReturn(mCurrentURI, aURI);
-  }
-
-  *aURI = nullptr;
+  nsCOMPtr<nsIURI> uri = mCurrentURI;
+  uri.forget(aURI);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDocShell::GetReferringURI(nsIURI** aURI)
 {
   NS_ENSURE_ARG_POINTER(aURI);
 
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -3690,19 +3690,16 @@ nsContentUtils::LoadImage(nsIURI* aURI, 
 
   nsCOMPtr<nsILoadGroup> loadGroup = aLoadingDocument->GetDocumentLoadGroup();
 
   nsIURI *documentURI = aLoadingDocument->GetDocumentURI();
 
   NS_ASSERTION(loadGroup || IsFontTableURI(documentURI),
                "Could not get loadgroup; onload may fire too early");
 
-  // Make the URI immutable so people won't change it under us
-  NS_TryToSetImmutable(aURI);
-
   // XXXbz using "documentURI" for the initialDocumentURI is not quite
   // right, but the best we can do here...
   return imgLoader->LoadImage(aURI,                 /* uri to load */
                               documentURI,          /* initialDocumentURI */
                               aReferrer,            /* referrer */
                               aReferrerPolicy,      /* referrer policy */
                               aLoadingPrincipal,    /* loading principal */
                               aRequestContextID,    /* request context ID */
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -3021,17 +3021,17 @@ nsDocument::StopDocumentLoad()
     mParser->Terminate();
   }
 }
 
 void
 nsIDocument::SetDocumentURI(nsIURI* aURI)
 {
   nsCOMPtr<nsIURI> oldBase = GetDocBaseURI();
-  mDocumentURI = NS_TryToMakeImmutable(aURI);
+  mDocumentURI = aURI;
   nsIURI* newBase = GetDocBaseURI();
 
   bool equalBases = false;
   // Changing just the ref of a URI does not change how relative URIs would
   // resolve wrt to it, so we can treat the bases as equal as long as they're
   // equal ignoring the ref.
   if (oldBase && newBase) {
     oldBase->EqualsExceptRef(newBase, &equalBases);
@@ -3636,21 +3636,17 @@ nsIDocument::SetBaseURI(nsIURI* aURI)
   if (aURI && mDocumentBaseURI) {
     bool equalBases = false;
     mDocumentBaseURI->Equals(aURI, &equalBases);
     if (equalBases) {
       return;
     }
   }
 
-  if (aURI) {
-    mDocumentBaseURI = NS_TryToMakeImmutable(aURI);
-  } else {
-    mDocumentBaseURI = nullptr;
-  }
+  mDocumentBaseURI = aURI;
   RefreshLinkHrefs();
 }
 
 URLExtraData*
 nsIDocument::DefaultStyleAttrURLData()
 {
   MOZ_ASSERT(NS_IsMainThread());
   nsIURI* baseURI = GetDocBaseURI();
--- a/dom/base/nsImageLoadingContent.cpp
+++ b/dom/base/nsImageLoadingContent.cpp
@@ -727,21 +727,18 @@ nsImageLoadingContent::GetRequestType(im
 }
 
 already_AddRefed<nsIURI>
 nsImageLoadingContent::GetCurrentURI(ErrorResult& aError)
 {
   nsCOMPtr<nsIURI> uri;
   if (mCurrentRequest) {
     mCurrentRequest->GetURI(getter_AddRefs(uri));
-  } else if (mCurrentURI) {
-    nsresult rv = NS_EnsureSafeToReturn(mCurrentURI, getter_AddRefs(uri));
-    if (NS_FAILED(rv)) {
-      aError.Throw(rv);
-    }
+  } else {
+    uri = mCurrentURI;
   }
 
   return uri.forget();
 }
 
 NS_IMETHODIMP
 nsImageLoadingContent::GetCurrentURI(nsIURI** aURI)
 {
@@ -867,18 +864,16 @@ nsImageLoadingContent::LoadImage(const n
   FireEvent(NS_LITERAL_STRING("loadstart"));
 
   // Parse the URI string to get image URI
   nsCOMPtr<nsIURI> imageURI;
   nsresult rv = StringToURI(aNewURI, doc, getter_AddRefs(imageURI));
   NS_ENSURE_SUCCESS(rv, rv);
   // XXXbiesi fire onerror if that failed?
 
-  NS_TryToSetImmutable(imageURI);
-
   return LoadImage(imageURI, aForce, aNotify, aImageLoadType, false, doc,
                    nsIRequest::LOAD_NORMAL, aTriggeringPrincipal);
 }
 
 nsresult
 nsImageLoadingContent::LoadImage(nsIURI* aNewURI,
                                  bool aForce,
                                  bool aNotify,
--- a/dom/base/nsObjectLoadingContent.cpp
+++ b/dom/base/nsObjectLoadingContent.cpp
@@ -1598,19 +1598,17 @@ nsObjectLoadingContent::UpdateObjectPara
   nsCOMPtr<nsIURI> docBaseURI = thisElement->GetBaseURI();
   thisElement->GetAttr(kNameSpaceID_None, nsGkAtoms::codebase, codebaseStr);
 
   if (!codebaseStr.IsEmpty()) {
     rv = nsContentUtils::NewURIWithDocumentCharset(getter_AddRefs(newBaseURI),
                                                    codebaseStr,
                                                    thisElement->OwnerDoc(),
                                                    docBaseURI);
-    if (NS_SUCCEEDED(rv)) {
-      NS_TryToSetImmutable(newBaseURI);
-    } else {
+    if (NS_FAILED(rv)) {
       // Malformed URI
       LOG(("OBJLC [%p]: Could not parse plugin's codebase as a URI, "
            "will use document baseURI instead", this));
     }
   }
 
   nsAutoString rawTypeAttr;
   thisElement->GetAttr(kNameSpaceID_None, nsGkAtoms::type, rawTypeAttr);
@@ -1651,19 +1649,17 @@ nsObjectLoadingContent::UpdateObjectPara
                              newBaseURI,
                              getter_AddRefs(rewrittenURI));
     if (rewrittenURI) {
       newURI = rewrittenURI;
       mRewrittenYoutubeEmbed = true;
       newMime = NS_LITERAL_CSTRING("text/html");
     }
 
-    if (NS_SUCCEEDED(rv)) {
-      NS_TryToSetImmutable(newURI);
-    } else {
+    if (NS_FAILED(rv)) {
       stateInvalid = true;
     }
   }
 
   // For eAllowPluginSkipChannel tags, if we have a non-plugin type, but can get
   // a plugin type from the extension, prefer that to falling back to a channel.
   if (!IsPluginType(GetTypeOfContent(newMime, mSkipFakePlugins)) && newURI &&
       (caps & eAllowPluginSkipChannel) &&
--- a/dom/html/nsHTMLDocument.cpp
+++ b/dom/html/nsHTMLDocument.cpp
@@ -1036,17 +1036,16 @@ nsHTMLDocument::SetDomain(const nsAStrin
 
   nsCOMPtr<nsIURI> newURI = RegistrableDomainSuffixOfInternal(aDomain, uri);
   if (!newURI) {
     // Error: illegal domain
     rv.Throw(NS_ERROR_DOM_BAD_DOCUMENT_DOMAIN);
     return;
   }
 
-  NS_TryToSetImmutable(newURI);
   rv = NodePrincipal()->SetDomain(newURI);
 }
 
 already_AddRefed<nsIChannel>
 nsHTMLDocument::CreateDummyChannelForCookies(nsIURI* aCodebaseURI)
 {
   // The cookie service reads the privacy status of the channel we pass to it in
   // order to determine which cookie database to query.  In some cases we don't
--- a/ipc/glue/URIParams.ipdlh
+++ b/ipc/glue/URIParams.ipdlh
@@ -11,17 +11,16 @@ namespace mozilla {
 namespace ipc {
 
 struct SimpleURIParams
 {
   nsCString scheme;
   nsCString path;
   nsCString ref;
   nsCString query;
-  bool isMutable;
 };
 
 struct StandardURLSegment
 {
   uint32_t position;
   int32_t length;
 };
 
@@ -38,17 +37,16 @@ struct StandardURLParams
   StandardURLSegment host;
   StandardURLSegment path;
   StandardURLSegment filePath;
   StandardURLSegment directory;
   StandardURLSegment baseName;
   StandardURLSegment extension;
   StandardURLSegment query;
   StandardURLSegment ref;
-  bool isMutable;
   bool supportsFileURL;
 };
 
 struct JARURIParams
 {
   URIParams jarFile;
   URIParams jarEntry;
   nsCString charset;
--- a/modules/libjar/nsJARURI.cpp
+++ b/modules/libjar/nsJARURI.cpp
@@ -402,18 +402,16 @@ nsJARURI::SetSpecWithBase(const nsACStri
     if (!RFindInReadable(NS_JAR_DELIMITER, delim_begin, delim_end)) {
         return NS_ERROR_MALFORMED_URI;
     }
 
     rv = ioServ->NewURI(Substring(begin, delim_begin), mCharsetHint.get(),
                         aBaseURL, getter_AddRefs(mJARFile));
     if (NS_FAILED(rv)) return rv;
 
-    NS_TryToSetImmutable(mJARFile);
-
     // skip over any extra '/' chars
     while (*delim_end == '/')
         ++delim_end;
 
     aSpec.EndReading(end); // set to the original 'end'
     return SetJAREntry(Substring(delim_end, end));
 }
 
@@ -917,18 +915,16 @@ nsJARURI::CloneWithJARFileInternal(nsIUR
     }
 
     nsresult rv;
 
     nsCOMPtr<nsIURI> newJARFile;
     rv = jarFile->Clone(getter_AddRefs(newJARFile));
     if (NS_FAILED(rv)) return rv;
 
-    NS_TryToSetImmutable(newJARFile);
-
     nsCOMPtr<nsIURI> newJAREntryURI;
     if (refHandlingMode == eHonorRef) {
       rv = mJAREntry->Clone(getter_AddRefs(newJAREntryURI));
     } else if (refHandlingMode == eReplaceRef) {
       rv = mJAREntry->CloneWithNewRef(newRef, getter_AddRefs(newJAREntryURI));
     } else {
       rv = mJAREntry->CloneIgnoringRef(getter_AddRefs(newJAREntryURI));
     }
@@ -944,19 +940,21 @@ nsJARURI::CloneWithJARFileInternal(nsIUR
     *result = uri;
 
     return NS_OK;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 
 NS_IMETHODIMP
-nsJARURI::GetInnerURI(nsIURI **uri)
+nsJARURI::GetInnerURI(nsIURI **aURI)
 {
-    return NS_EnsureSafeToReturn(mJARFile, uri);
+    nsCOMPtr<nsIURI> uri = mJARFile;
+    uri.forget(aURI);
+    return NS_OK;
 }
 
 NS_IMETHODIMP
 nsJARURI::GetInnermostURI(nsIURI** uri)
 {
     return NS_ImplGetInnermostURI(this, uri);
 }
 
--- a/netwerk/base/nsINetUtil.idl
+++ b/netwerk/base/nsINetUtil.idl
@@ -70,24 +70,16 @@ interface nsINetUtil : nsISupports
    * @param aURI the URI in question
    * @param aFlags the flags we're testing for.
    *
    * @return whether any of the protocol handlers involved have all the flags
    *         in aFlags.
    */
   boolean URIChainHasFlags(in nsIURI aURI, in unsigned long aFlags);
 
-  /**
-   * Take aURI and produce an immutable version of it for the caller.  If aURI
-   * is immutable this will be aURI itself; otherwise this will be a clone,
-   * marked immutable if possible.  Passing null to this method is allowed; in
-   * that case it will return null.
-   */
-  nsIURI toImmutableURI(in nsIURI aURI);
-
   /** Escape every character with its %XX-escaped equivalent */
   const unsigned long ESCAPE_ALL = 0;
 
   /** Leave alphanumeric characters intact and %XX-escape all others */
   const unsigned long ESCAPE_XALPHAS = 1;
 
   /** Leave alphanumeric characters intact, convert spaces to '+',
       %XX-escape all others */
--- a/netwerk/base/nsIOService.cpp
+++ b/netwerk/base/nsIOService.cpp
@@ -1596,31 +1596,16 @@ nsIOService::URIChainHasFlags(nsIURI   *
 
         nestedURI = do_QueryInterface(innerURI);
     }
 
     return rv;
 }
 
 NS_IMETHODIMP
-nsIOService::ToImmutableURI(nsIURI* uri, nsIURI** result)
-{
-    if (!uri) {
-        *result = nullptr;
-        return NS_OK;
-    }
-
-    nsresult rv = NS_EnsureSafeToReturn(uri, result);
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    NS_TryToSetImmutable(*result);
-    return NS_OK;
-}
-
-NS_IMETHODIMP
 nsIOService::SetManageOfflineStatus(bool aManage)
 {
     LOG(("nsIOService::SetManageOfflineStatus aManage=%d\n", aManage));
     mManageLinkStatus = aManage;
 
     // When detection is not activated, the default connectivity state is true.
     if (!mManageLinkStatus) {
         SetConnectivityInternal(true);
--- a/netwerk/base/nsIStandardURL.idl
+++ b/netwerk/base/nsIStandardURL.idl
@@ -1,26 +1,26 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include "nsIMutable.idl"
+#include "nsISupports.idl"
 
 interface nsIURI;
 interface nsIURIMutator;
 
 /**
  * nsIStandardURL defines the interface to an URL with the standard
  * file path format common to protocols like http, ftp, and file.
  * It supports initialization from a relative path and provides
  * some customization on how URLs are normalized.
  */
 [scriptable, builtinclass, uuid(babd6cca-ebe7-4329-967c-d6b9e33caa81)]
-interface nsIStandardURL : nsIMutable
+interface nsIStandardURL : nsISupports
 {
     /**
      * blah:foo/bar    => blah://foo/bar
      * blah:/foo/bar   => blah:///foo/bar
      * blah://foo/bar  => blah://foo/bar
      * blah:///foo/bar => blah:///foo/bar
      */
     const unsigned long URLTYPE_STANDARD        = 1;
--- a/netwerk/base/nsNetUtil.cpp
+++ b/netwerk/base/nsNetUtil.cpp
@@ -2338,76 +2338,16 @@ nsresult
 NS_ImplGetInnermostURI(nsINestedURI *nestedURI, nsIURI **result)
 {
     // Make it safe to use swap()
     *result = nullptr;
 
     return NS_DoImplGetInnermostURI(nestedURI, result);
 }
 
-nsresult
-NS_EnsureSafeToReturn(nsIURI *uri, nsIURI **result)
-{
-    MOZ_ASSERT(uri, "Must have a URI");
-
-    // Assume mutable until told otherwise
-    bool isMutable = true;
-    nsCOMPtr<nsIMutable> mutableObj(do_QueryInterface(uri));
-    if (mutableObj) {
-        nsresult rv = mutableObj->GetMutable(&isMutable);
-        isMutable = NS_FAILED(rv) || isMutable;
-    }
-
-    if (!isMutable) {
-        NS_ADDREF(*result = uri);
-        return NS_OK;
-    }
-
-    nsresult rv = uri->Clone(result);
-    if (NS_SUCCEEDED(rv) && !*result) {
-        NS_ERROR("nsIURI.clone contract was violated");
-        return NS_ERROR_UNEXPECTED;
-    }
-
-    return rv;
-}
-
-void
-NS_TryToSetImmutable(nsIURI *uri)
-{
-    nsCOMPtr<nsIMutable> mutableObj(do_QueryInterface(uri));
-    if (mutableObj) {
-        mutableObj->SetMutable(false);
-    }
-}
-
-already_AddRefed<nsIURI>
-NS_TryToMakeImmutable(nsIURI *uri,
-                      nsresult *outRv /* = nullptr */)
-{
-    nsresult rv;
-    nsCOMPtr<nsINetUtil> util = do_GetNetUtil(&rv);
-
-    nsCOMPtr<nsIURI> result;
-    if (NS_SUCCEEDED(rv)) {
-        NS_ASSERTION(util, "do_GetNetUtil lied");
-        rv = util->ToImmutableURI(uri, getter_AddRefs(result));
-    }
-
-    if (NS_FAILED(rv)) {
-        result = uri;
-    }
-
-    if (outRv) {
-        *outRv = rv;
-    }
-
-    return result.forget();
-}
-
 already_AddRefed<nsIURI>
 NS_GetInnermostURI(nsIURI *aURI)
 {
     MOZ_ASSERT(aURI, "Must have URI");
 
     nsCOMPtr<nsIURI> uri = aURI;
 
     nsCOMPtr<nsINestedURI> nestedURI(do_QueryInterface(uri));
--- a/netwerk/base/nsNetUtil.h
+++ b/netwerk/base/nsNetUtil.h
@@ -789,36 +789,16 @@ bool NS_IsOffline();
  * Note that NS_DoImplGetInnermostURI is "private" -- call
  * NS_ImplGetInnermostURI instead.
  */
 nsresult NS_DoImplGetInnermostURI(nsINestedURI *nestedURI, nsIURI **result);
 
 nsresult NS_ImplGetInnermostURI(nsINestedURI *nestedURI, nsIURI **result);
 
 /**
- * Helper function that ensures that |result| is a URI that's safe to
- * return.  If |uri| is immutable, just returns it, otherwise returns
- * a clone.  |uri| must not be null.
- */
-nsresult NS_EnsureSafeToReturn(nsIURI *uri, nsIURI **result);
-
-/**
- * Helper function that tries to set the argument URI to be immutable
- */
-void NS_TryToSetImmutable(nsIURI *uri);
-
-/**
- * Helper function for calling ToImmutableURI.  If all else fails, returns
- * the input URI.  The optional second arg indicates whether we had to fall
- * back to the input URI.  Passing in a null URI is ok.
- */
-already_AddRefed<nsIURI> NS_TryToMakeImmutable(nsIURI *uri,
-                                               nsresult *outRv = nullptr);
-
-/**
  * Helper function for testing whether the given URI, or any of its
  * inner URIs, has all the given protocol flags.
  */
 nsresult NS_URIChainHasFlags(nsIURI   *uri,
                              uint32_t  flags,
                              bool     *result);
 
 /**
--- a/netwerk/base/nsSimpleNestedURI.cpp
+++ b/netwerk/base/nsSimpleNestedURI.cpp
@@ -17,17 +17,16 @@ namespace mozilla {
 namespace net {
 
 NS_IMPL_ISUPPORTS_INHERITED(nsSimpleNestedURI, nsSimpleURI, nsINestedURI)
 
 nsSimpleNestedURI::nsSimpleNestedURI(nsIURI* innerURI)
     : mInnerURI(innerURI)
 {
     NS_ASSERTION(innerURI, "Must have inner URI");
-    NS_TryToSetImmutable(innerURI);
 }
 
 // nsISerializable
 
 NS_IMETHODIMP
 nsSimpleNestedURI::Read(nsIObjectInputStream *aStream)
 {
     NS_NOTREACHED("Use nsIURIMutator.read() instead");
@@ -35,27 +34,23 @@ nsSimpleNestedURI::Read(nsIObjectInputSt
 }
 
 nsresult
 nsSimpleNestedURI::ReadPrivate(nsIObjectInputStream *aStream)
 {
     nsresult rv = nsSimpleURI::ReadPrivate(aStream);
     if (NS_FAILED(rv)) return rv;
 
-    NS_ASSERTION(!mMutable, "How did that happen?");
-
     nsCOMPtr<nsISupports> supports;
     rv = aStream->ReadObject(true, getter_AddRefs(supports));
     if (NS_FAILED(rv)) return rv;
 
     mInnerURI = do_QueryInterface(supports, &rv);
     if (NS_FAILED(rv)) return rv;
 
-    NS_TryToSetImmutable(mInnerURI);
-
     return rv;
 }
 
 NS_IMETHODIMP
 nsSimpleNestedURI::Write(nsIObjectOutputStream* aStream)
 {
     nsCOMPtr<nsISerializable> serializable = do_QueryInterface(mInnerURI);
     if (!serializable) {
@@ -98,29 +93,29 @@ nsSimpleNestedURI::Deserialize(const moz
         return false;
     }
 
     const SimpleNestedURIParams& params = aParams.get_SimpleNestedURIParams();
     if (!nsSimpleURI::Deserialize(params.simpleParams()))
         return false;
 
     mInnerURI = DeserializeURI(params.innerURI());
-
-    NS_TryToSetImmutable(mInnerURI);
     return true;
 }
 
 // nsINestedURI
 
 NS_IMETHODIMP
-nsSimpleNestedURI::GetInnerURI(nsIURI** uri)
+nsSimpleNestedURI::GetInnerURI(nsIURI** aURI)
 {
     NS_ENSURE_TRUE(mInnerURI, NS_ERROR_NOT_INITIALIZED);
 
-    return NS_EnsureSafeToReturn(mInnerURI, uri);
+    nsCOMPtr<nsIURI> uri = mInnerURI;
+    uri.forget(aURI);
+    return NS_OK;
 }
 
 NS_IMETHODIMP
 nsSimpleNestedURI::GetInnermostURI(nsIURI** uri)
 {
     return NS_ImplGetInnermostURI(this, uri);
 }
 
@@ -172,17 +167,16 @@ nsSimpleNestedURI::StartClone(nsSimpleUR
     }
 
     if (NS_FAILED(rv)) {
         return nullptr;
     }
 
     nsSimpleNestedURI* url = new nsSimpleNestedURI(innerClone);
     SetRefOnClone(url, refHandlingMode, newRef);
-    url->SetMutable(false);
 
     return url;
 }
 
 // nsIClassInfo overrides
 
 NS_IMETHODIMP
 nsSimpleNestedURI::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc)
@@ -203,17 +197,14 @@ NS_IMPL_NSIURIMUTATOR_ISUPPORTS(nsSimple
 NS_IMETHODIMP
 nsSimpleNestedURI::Mutate(nsIURIMutator** aMutator)
 {
     RefPtr<nsSimpleNestedURI::Mutator> mutator = new nsSimpleNestedURI::Mutator();
     nsresult rv = mutator->InitFromURI(this);
     if (NS_FAILED(rv)) {
         return rv;
     }
-    // StartClone calls SetMutable(false) but we need the mutator clone
-    // to be mutable
-    mutator->ResetMutable();
     mutator.forget(aMutator);
     return NS_OK;
 }
 
 } // namespace net
 } // namespace mozilla
--- a/netwerk/base/nsSimpleNestedURI.h
+++ b/netwerk/base/nsSimpleNestedURI.h
@@ -1,21 +1,17 @@
 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /**
  * URI class to be used for cases when a simple URI actually resolves to some
  * other sort of URI, with the latter being what's loaded when the load
- * happens.  All objects of this class should always be immutable, so that the
- * inner URI and this URI don't get out of sync.  The Clone() implementation
- * will guarantee this for the clone, but it's up to the protocol handlers
- * creating these URIs to ensure that in the first place.  The innerURI passed
- * to this URI will be set immutable if possible.
+ * happens.
  */
 
 #ifndef nsSimpleNestedURI_h__
 #define nsSimpleNestedURI_h__
 
 #include "nsCOMPtr.h"
 #include "nsSimpleURI.h"
 #include "nsINestedURI.h"
@@ -95,17 +91,16 @@ public:
         Read(nsIObjectInputStream* aStream) override
         {
             return InitFromInputStream(aStream);
         }
 
         MOZ_MUST_USE NS_IMETHOD
         Finalize(nsIURI** aURI) override
         {
-            mURI->mMutable = false;
             mURI.forget(aURI);
             return NS_OK;
         }
 
         MOZ_MUST_USE NS_IMETHOD
         SetSpec(const nsACString& aSpec, nsIURIMutator** aMutator) override
         {
             if (aMutator) {
@@ -116,23 +111,16 @@ public:
 
         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;
     };
 
     friend BaseURIMutator<nsSimpleNestedURI>;
 };
 
 } // namespace net
 } // namespace mozilla
--- a/netwerk/base/nsSimpleURI.cpp
+++ b/netwerk/base/nsSimpleURI.cpp
@@ -44,27 +44,26 @@ nsSimpleURI::From(nsIURI* aURI)
 
     return uri.forget();
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsSimpleURI methods:
 
 nsSimpleURI::nsSimpleURI()
-    : mMutable(true)
-    , mIsRefValid(false)
+    : mIsRefValid(false)
     , mIsQueryValid(false)
 {
 }
 
 NS_IMPL_ADDREF(nsSimpleURI)
 NS_IMPL_RELEASE(nsSimpleURI)
 NS_INTERFACE_TABLE_HEAD(nsSimpleURI)
 NS_INTERFACE_TABLE(nsSimpleURI, nsIURI, nsISerializable,
-                   nsIClassInfo, nsIMutable, nsIIPCSerializableURI)
+                   nsIClassInfo, nsIIPCSerializableURI)
 NS_INTERFACE_TABLE_TO_MAP_SEGUE
   if (aIID.Equals(kThisSimpleURIImplementationCID))
     foundInterface = static_cast<nsIURI*>(this);
   else
   NS_INTERFACE_MAP_ENTRY(nsISizeOf)
 NS_INTERFACE_MAP_END
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -80,17 +79,17 @@ nsSimpleURI::Read(nsIObjectInputStream *
 nsresult
 nsSimpleURI::ReadPrivate(nsIObjectInputStream *aStream)
 {
     nsresult rv;
 
     bool isMutable;
     rv = aStream->ReadBoolean(&isMutable);
     if (NS_FAILED(rv)) return rv;
-    mMutable = isMutable;
+    Unused << isMutable;
 
     rv = aStream->ReadCString(mScheme);
     if (NS_FAILED(rv)) return rv;
 
     rv = aStream->ReadCString(mPath);
     if (NS_FAILED(rv)) return rv;
 
     bool isRefValid;
@@ -120,17 +119,17 @@ nsSimpleURI::ReadPrivate(nsIObjectInputS
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsSimpleURI::Write(nsIObjectOutputStream* aStream)
 {
     nsresult rv;
 
-    rv = aStream->WriteBoolean(mMutable);
+    rv = aStream->WriteBoolean(false); // former mMutable
     if (NS_FAILED(rv)) return rv;
 
     rv = aStream->WriteStringZ(mScheme.get());
     if (NS_FAILED(rv)) return rv;
 
     rv = aStream->WriteStringZ(mPath.get());
     if (NS_FAILED(rv)) return rv;
 
@@ -171,18 +170,16 @@ nsSimpleURI::Serialize(URIParams& aParam
     }
 
     if (mIsQueryValid) {
       params.query() = mQuery;
     } else {
       params.query().SetIsVoid(true);
     }
 
-    params.isMutable() = mMutable;
-
     aParams = params;
 }
 
 bool
 nsSimpleURI::Deserialize(const URIParams& aParams)
 {
     if (aParams.type() != URIParams::TSimpleURIParams) {
         NS_ERROR("Received unknown parameters from the other process!");
@@ -205,18 +202,16 @@ nsSimpleURI::Deserialize(const URIParams
     if (params.query().IsVoid()) {
         mQuery.Truncate();
         mIsQueryValid = false;
     } else {
         mQuery = params.query();
         mIsQueryValid = true;
     }
 
-    mMutable = params.isMutable();
-
     return true;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsIURI methods:
 
 NS_IMETHODIMP
 nsSimpleURI::GetSpec(nsACString &result)
@@ -288,18 +283,16 @@ nsSimpleURI::GetHasRef(bool *result)
 {
     *result = mIsRefValid;
     return NS_OK;
 }
 
 nsresult
 nsSimpleURI::SetSpecInternal(const nsACString &aSpec)
 {
-    NS_ENSURE_STATE(mMutable);
-
     nsresult rv = net_ExtractURLScheme(aSpec, mScheme);
     if (NS_FAILED(rv)) {
         return rv;
     }
 
     nsAutoCString spec;
     rv = net_FilterAndEscapeURI(aSpec, esc_OnlyNonASCII, spec);
     if (NS_FAILED(rv)) {
@@ -318,18 +311,16 @@ nsSimpleURI::GetScheme(nsACString &resul
 {
     result = mScheme;
     return NS_OK;
 }
 
 nsresult
 nsSimpleURI::SetScheme(const nsACString &scheme)
 {
-    NS_ENSURE_STATE(mMutable);
-
     const nsPromiseFlatCString &flat = PromiseFlatCString(scheme);
     if (!net_IsValidScheme(flat)) {
         NS_WARNING("the given url scheme contains invalid characters");
         return NS_ERROR_MALFORMED_URI;
     }
 
     mScheme = scheme;
     ToLowerCase(mScheme);
@@ -359,81 +350,71 @@ NS_IMETHODIMP
 nsSimpleURI::GetUsername(nsACString &result)
 {
     return NS_ERROR_FAILURE;
 }
 
 nsresult
 nsSimpleURI::SetUsername(const nsACString &userName)
 {
-    NS_ENSURE_STATE(mMutable);
-
     return NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
 nsSimpleURI::GetPassword(nsACString &result)
 {
     return NS_ERROR_FAILURE;
 }
 
 nsresult
 nsSimpleURI::SetPassword(const nsACString &password)
 {
-    NS_ENSURE_STATE(mMutable);
-
     return NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
 nsSimpleURI::GetHostPort(nsACString &result)
 {
     // Note: Audit all callers before changing this to return an empty
     // string -- CAPS and UI code may depend on this throwing.
     // Note: If this is changed, change GetAsciiHostPort as well.
     return NS_ERROR_FAILURE;
 }
 
 nsresult
 nsSimpleURI::SetHostPort(const nsACString &result)
 {
-    NS_ENSURE_STATE(mMutable);
-
     return NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
 nsSimpleURI::GetHost(nsACString &result)
 {
     // Note: Audit all callers before changing this to return an empty
     // string -- CAPS and UI code depend on this throwing.
     return NS_ERROR_FAILURE;
 }
 
 nsresult
 nsSimpleURI::SetHost(const nsACString &host)
 {
-    NS_ENSURE_STATE(mMutable);
-
     return NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
 nsSimpleURI::GetPort(int32_t *result)
 {
     // Note: Audit all callers before changing this to return an empty
     // string -- CAPS and UI code may depend on this throwing.
     return NS_ERROR_FAILURE;
 }
 
 nsresult
 nsSimpleURI::SetPort(int32_t port)
 {
-    NS_ENSURE_STATE(mMutable);
-
     return NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
 nsSimpleURI::GetPathQueryRef(nsACString &result)
 {
     result = mPath;
     if (mIsQueryValid) {
@@ -444,18 +425,16 @@ nsSimpleURI::GetPathQueryRef(nsACString 
     }
 
     return NS_OK;
 }
 
 nsresult
 nsSimpleURI::SetPathQueryRef(const nsACString &aPath)
 {
-    NS_ENSURE_STATE(mMutable);
-
     return SetPathQueryRefEscaped(aPath, true);
 }
 nsresult
 nsSimpleURI::SetPathQueryRefEscaped(const nsACString &aPath, bool aNeedsEscape)
 {
     nsresult rv;
     nsAutoCString path;
     if (aNeedsEscape) {
@@ -527,18 +506,16 @@ nsSimpleURI::GetRef(nsACString &result)
     return NS_OK;
 }
 
 // NOTE: SetRef("") removes our ref, whereas SetRef("#") sets it to the empty
 // string (and will result in .spec and .path having a terminal #).
 nsresult
 nsSimpleURI::SetRef(const nsACString &aRef)
 {
-    NS_ENSURE_STATE(mMutable);
-
     nsAutoCString ref;
     nsresult rv = NS_EscapeURL(aRef, esc_OnlyNonASCII, ref, fallible);
     if (NS_FAILED(rv)) {
         return rv;
     }
 
     if (ref.IsEmpty()) {
         // Empty string means to remove ref completely.
@@ -672,18 +649,16 @@ nsresult
 nsSimpleURI::CloneInternal(nsSimpleURI::RefHandlingEnum refHandlingMode,
                            const nsACString &newRef,
                            nsIURI** result)
 {
     RefPtr<nsSimpleURI> url = StartClone(refHandlingMode, newRef);
     if (!url)
         return NS_ERROR_OUT_OF_MEMORY;
 
-    // Note: |url| may well have mMutable false at this point, so
-    // don't call any setter methods.
     url->mScheme = mScheme;
     url->mPath = mPath;
 
     url->mIsQueryValid = mIsQueryValid;
     if (url->mIsQueryValid) {
       url->mQuery = mQuery;
     }
 
@@ -777,35 +752,16 @@ nsSimpleURI::GetFlags(uint32_t *aFlags)
 NS_IMETHODIMP
 nsSimpleURI::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc)
 {
     *aClassIDNoAlloc = kSimpleURICID;
     return NS_OK;
 }
 
 //----------------------------------------------------------------------------
-// nsSimpleURI::nsISimpleURI
-//----------------------------------------------------------------------------
-NS_IMETHODIMP
-nsSimpleURI::GetMutable(bool *value)
-{
-    *value = mMutable;
-    return NS_OK;
-}
-
-NS_IMETHODIMP
-nsSimpleURI::SetMutable(bool value)
-{
-    NS_ENSURE_ARG(mMutable || !value);
-
-    mMutable = value;
-    return NS_OK;
-}
-
-//----------------------------------------------------------------------------
 // nsSimpleURI::nsISizeOf
 //----------------------------------------------------------------------------
 
 size_t
 nsSimpleURI::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const
 {
   return mScheme.SizeOfExcludingThisIfUnshared(aMallocSizeOf) +
          mPath.SizeOfExcludingThisIfUnshared(aMallocSizeOf) +
@@ -841,18 +797,16 @@ nsSimpleURI::GetQuery(nsACString& aQuery
         aQuery = mQuery;
     }
     return NS_OK;
 }
 
 nsresult
 nsSimpleURI::SetQuery(const nsACString& aQuery)
 {
-    NS_ENSURE_STATE(mMutable);
-
     nsAutoCString query;
     nsresult rv = NS_EscapeURL(aQuery, esc_OnlyNonASCII, query, fallible);
     if (NS_FAILED(rv)) {
         return rv;
     }
 
     if (query.IsEmpty()) {
         // Empty string means to remove query completely.
--- a/netwerk/base/nsSimpleURI.h
+++ b/netwerk/base/nsSimpleURI.h
@@ -6,17 +6,16 @@
 #ifndef nsSimpleURI_h__
 #define nsSimpleURI_h__
 
 #include "mozilla/MemoryReporting.h"
 #include "nsIURI.h"
 #include "nsISerializable.h"
 #include "nsString.h"
 #include "nsIClassInfo.h"
-#include "nsIMutable.h"
 #include "nsISizeOf.h"
 #include "nsIIPCSerializableURI.h"
 #include "nsIURIMutator.h"
 
 namespace mozilla {
 namespace net {
 
 #define NS_THIS_SIMPLEURI_IMPLEMENTATION_CID         \
@@ -26,30 +25,28 @@ namespace net {
     0x470b,                                          \
     {0xb9, 0xb9, 0x9f, 0xd9, 0x46, 0x2b, 0x5e, 0x19} \
 }
 
 class nsSimpleURI
     : public nsIURI
     , public nsISerializable
     , public nsIClassInfo
-    , public nsIMutable
     , public nsISizeOf
     , public nsIIPCSerializableURI
 {
 protected:
     nsSimpleURI();
     virtual ~nsSimpleURI() = default;
 
 public:
     NS_DECL_THREADSAFE_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:
 
     bool Equals(nsSimpleURI* aOther)
     {
--- a/netwerk/base/nsStandardURL.cpp
+++ b/netwerk/base/nsStandardURL.cpp
@@ -74,26 +74,16 @@ constexpr bool TestForInvalidHostCharact
     return (c > 0 && c < 32) || // The control characters are [1, 31]
            c == ' ' || c == '#' || c == '/' || c == ':' || c == '?' ||
            c == '@' || c == '[' || c == '\\' || c == ']' || c == '*' ||
            c == '<' || c == '>' || c == '|' || c == '"';
 }
 constexpr ASCIIMaskArray sInvalidHostChars = CreateASCIIMask(TestForInvalidHostCharacters);
 
 //----------------------------------------------------------------------------
-
-#define ENSURE_MUTABLE() \
-  PR_BEGIN_MACRO \
-    if (!mMutable) { \
-        NS_WARNING("attempt to modify an immutable nsStandardURL"); \
-        return NS_ERROR_ABORT; \
-    } \
-  PR_END_MACRO
-
-//----------------------------------------------------------------------------
 // nsStandardURL::nsSegmentEncoder
 //----------------------------------------------------------------------------
 
 nsStandardURL::nsSegmentEncoder::nsSegmentEncoder(const Encoding* encoding)
   : mEncoding(encoding)
 {
   if (mEncoding == UTF_8_ENCODING) {
     mEncoding = nullptr;
@@ -176,17 +166,16 @@ static StaticMutex gAllURLsMutex;
 static LinkedList<nsStandardURL> gAllURLs;
 #endif
 
 nsStandardURL::nsStandardURL(bool aSupportsFileURL, bool aTrackURL)
     : mDefaultPort(-1)
     , mPort(-1)
     , mDisplayHost(nullptr)
     , mURLType(URLTYPE_STANDARD)
-    , mMutable(true)
     , mSupportsFileURL(aSupportsFileURL)
     , mCheckedIfHostA(false)
 {
     LOG(("Creating nsStandardURL @%p\n", this));
 
     // gInitialized changes value only once (false->true) on the main thread.
     // It's OK to race here because in the worst case we'll just
     // dispatch a noop runnable to the main thread.
@@ -1200,17 +1189,16 @@ NS_IMPL_RELEASE(nsStandardURL)
 NS_INTERFACE_MAP_BEGIN(nsStandardURL)
     NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStandardURL)
     NS_INTERFACE_MAP_ENTRY(nsIURI)
     NS_INTERFACE_MAP_ENTRY(nsIURL)
     NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIFileURL, mSupportsFileURL)
     NS_INTERFACE_MAP_ENTRY(nsIStandardURL)
     NS_INTERFACE_MAP_ENTRY(nsISerializable)
     NS_INTERFACE_MAP_ENTRY(nsIClassInfo)
-    NS_INTERFACE_MAP_ENTRY(nsIMutable)
     NS_INTERFACE_MAP_ENTRY(nsIIPCSerializableURI)
     NS_INTERFACE_MAP_ENTRY(nsISensitiveInfoHiddenURI)
     // see nsStandardURL::Equals
     if (aIID.Equals(kThisImplCID))
         foundInterface = static_cast<nsIURI *>(this);
     else
     NS_INTERFACE_MAP_ENTRY(nsISizeOf)
 NS_INTERFACE_MAP_END
@@ -1497,18 +1485,16 @@ nsStandardURL::SetSpecInternal(const nsA
 {
     return SetSpecWithEncoding(input, nullptr);
 }
 
 nsresult
 nsStandardURL::SetSpecWithEncoding(const nsACString &input,
                                    const Encoding* encoding)
 {
-    ENSURE_MUTABLE();
-
     const nsPromiseFlatCString &flat = PromiseFlatCString(input);
     LOG(("nsStandardURL::SetSpec [spec=%s]\n", flat.get()));
 
     if (input.Length() > (uint32_t) net_GetURLMaxLength()) {
         return NS_ERROR_MALFORMED_URI;
     }
 
     // filter out unexpected chars "\r\n\t" if necessary
@@ -1584,18 +1570,16 @@ nsStandardURL::SetSpecWithEncoding(const
     }
 
     return rv;
 }
 
 nsresult
 nsStandardURL::SetScheme(const nsACString &input)
 {
-    ENSURE_MUTABLE();
-
     const nsPromiseFlatCString &scheme = PromiseFlatCString(input);
 
     LOG(("nsStandardURL::SetScheme [scheme=%s]\n", scheme.get()));
 
     if (scheme.IsEmpty()) {
         NS_WARNING("cannot remove the scheme from an url");
         return NS_ERROR_UNEXPECTED;
     }
@@ -1628,18 +1612,16 @@ nsStandardURL::SetScheme(const nsACStrin
     //     that operates on a substring.
     net_ToLowerCase((char *) mSpec.get(), mScheme.mLen);
     return NS_OK;
 }
 
 nsresult
 nsStandardURL::SetUserPass(const nsACString &input)
 {
-    ENSURE_MUTABLE();
-
     const nsPromiseFlatCString &userpass = PromiseFlatCString(input);
 
     LOG(("nsStandardURL::SetUserPass [userpass=%s]\n", userpass.get()));
 
     if (mURLType == URLTYPE_NO_AUTHORITY) {
         if (userpass.IsEmpty())
             return NS_OK;
         NS_WARNING("cannot set user:pass on no-auth url");
@@ -1738,18 +1720,16 @@ nsStandardURL::SetUserPass(const nsACStr
     }
 
     return NS_OK;
 }
 
 nsresult
 nsStandardURL::SetUsername(const nsACString &input)
 {
-    ENSURE_MUTABLE();
-
     const nsPromiseFlatCString &username = PromiseFlatCString(input);
 
     LOG(("nsStandardURL::SetUsername [username=%s]\n", username.get()));
 
     if (mURLType == URLTYPE_NO_AUTHORITY) {
         if (username.IsEmpty())
             return NS_OK;
         NS_WARNING("cannot set username on no-auth url");
@@ -1788,18 +1768,16 @@ nsStandardURL::SetUsername(const nsACStr
     }
 
     return NS_OK;
 }
 
 nsresult
 nsStandardURL::SetPassword(const nsACString &input)
 {
-    ENSURE_MUTABLE();
-
     const nsPromiseFlatCString &password = PromiseFlatCString(input);
 
     auto clearedPassword = MakeScopeExit([&password, this]() {
         // Check that if this method is called with the empty string then the
         // password is definitely cleared when exiting this method.
         if (password.IsEmpty()) {
             MOZ_DIAGNOSTIC_ASSERT(this->Password().IsEmpty());
         }
@@ -1876,18 +1854,16 @@ nsStandardURL::FindHostLimit(nsACString:
   }
 }
 
 // If aValue only has a host part and no port number, the port
 // will not be reset!!!
 nsresult
 nsStandardURL::SetHostPort(const nsACString &aValue)
 {
-    ENSURE_MUTABLE();
-
     // We cannot simply call nsIURI::SetHost because that would treat the name as
     // an IPv6 address (like http:://[server:443]/).  We also cannot call
     // nsIURI::SetHostPort because that isn't implemented.  Sadfaces.
 
     nsACString::const_iterator start, end;
     aValue.BeginReading(start);
     aValue.EndReading(end);
     nsACString::const_iterator iter(start);
@@ -1945,18 +1921,16 @@ nsStandardURL::SetHostPort(const nsACStr
 
     Unused << SetPort(port);
     return NS_OK;
 }
 
 nsresult
 nsStandardURL::SetHost(const nsACString &input)
 {
-    ENSURE_MUTABLE();
-
     const nsPromiseFlatCString &hostname = PromiseFlatCString(input);
 
     nsACString::const_iterator start, end;
     hostname.BeginReading(start);
     hostname.EndReading(end);
 
     FindHostLimit(start, end);
 
@@ -2053,18 +2027,16 @@ nsStandardURL::SetHost(const nsACString 
     // Now canonicalize the host to lowercase
     net_ToLowerCase(mSpec.BeginWriting() + mHost.mPos, mHost.mLen);
     return NS_OK;
 }
 
 nsresult
 nsStandardURL::SetPort(int32_t port)
 {
-    ENSURE_MUTABLE();
-
     LOG(("nsStandardURL::SetPort [port=%d]\n", port));
 
     if ((port == mPort) || (mPort == -1 && port == mDefaultPort))
         return NS_OK;
 
     // ports must be >= 0 and 16 bit
     // -1 == use default
     if (port < -1 || port > std::numeric_limits<uint16_t>::max())
@@ -2092,17 +2064,16 @@ nsStandardURL::SetPort(int32_t port)
  * The caller is responsible for:
  *  - Calling InvalidateCache (since our mSpec is changing).
  *  - Checking whether aNewPort is mDefaultPort (in which case the
  *    caller should pass aNewPort=-1).
  */
 void
 nsStandardURL::ReplacePortInSpec(int32_t aNewPort)
 {
-    MOZ_ASSERT(mMutable, "Caller should ensure we're mutable");
     NS_ASSERTION(aNewPort != mDefaultPort || mDefaultPort == -1,
                  "Caller should check its passed-in value and pass -1 instead of "
                  "mDefaultPort, to avoid encoding default port into mSpec");
 
     // Create the (possibly empty) string that we're planning to replace:
     nsAutoCString buf;
     if (mPort != -1) {
         buf.Assign(':');
@@ -2127,18 +2098,16 @@ nsStandardURL::ReplacePortInSpec(int32_t
     int32_t shift = buf.Length() - replacedLen;
     mAuthority.mLen += shift;
     ShiftFromPath(shift);
 }
 
 nsresult
 nsStandardURL::SetPathQueryRef(const nsACString &input)
 {
-    ENSURE_MUTABLE();
-
     const nsPromiseFlatCString &path = PromiseFlatCString(input);
     LOG(("nsStandardURL::SetPathQueryRef [path=%s]\n", path.get()));
 
     InvalidateCache();
 
     if (!path.IsEmpty()) {
         nsAutoCString spec;
 
@@ -2358,17 +2327,16 @@ nsresult nsStandardURL::CopyMembers(nsSt
     mFilepath = source->mFilepath;
     mDirectory = source->mDirectory;
     mBasename = source->mBasename;
     mExtension = source->mExtension;
     mQuery = source->mQuery;
     mRef = source->mRef;
     mURLType = source->mURLType;
     mParser = source->mParser;
-    mMutable = true;
     mSupportsFileURL = source->mSupportsFileURL;
     mCheckedIfHostA = source->mCheckedIfHostA;
     mDisplayHost = source->mDisplayHost;
 
     if (copyCached) {
         mFile = source->mFile;
     } else {
         InvalidateCache(true);
@@ -2775,18 +2743,16 @@ nsStandardURL::GetFileExtension(nsACStri
 {
     result = Extension();
     return NS_OK;
 }
 
 nsresult
 nsStandardURL::SetFilePath(const nsACString &input)
 {
-    ENSURE_MUTABLE();
-
     const nsPromiseFlatCString &flat = PromiseFlatCString(input);
     const char *filepath = flat.get();
 
     LOG(("nsStandardURL::SetFilePath [filepath=%s]\n", filepath));
 
     // if there isn't a filepath, then there can't be anything
     // after the path either.  this url is likely uninitialized.
     if (mFilepath.mLen < 0)
@@ -2868,18 +2834,16 @@ nsStandardURL::SetQuery(const nsACString
 {
     return SetQueryWithEncoding(input, nullptr);
 }
 
 nsresult
 nsStandardURL::SetQueryWithEncoding(const nsACString &input,
                                     const Encoding* encoding)
 {
-    ENSURE_MUTABLE();
-
     const nsPromiseFlatCString &flat = PromiseFlatCString(input);
     const char *query = flat.get();
 
     LOG(("nsStandardURL::SetQuery [query=%s]\n", query));
 
     if (IsUTFEncoding(encoding)) {
         encoding = nullptr;
     }
@@ -2944,18 +2908,16 @@ nsStandardURL::SetQueryWithEncoding(cons
         ShiftFromRef(shift);
     }
     return NS_OK;
 }
 
 nsresult
 nsStandardURL::SetRef(const nsACString &input)
 {
-    ENSURE_MUTABLE();
-
     const nsPromiseFlatCString &flat = PromiseFlatCString(input);
     const char *ref = flat.get();
 
     LOG(("nsStandardURL::SetRef [ref=%s]\n", ref));
 
     if (mPath.mLen < 0)
         return SetPathQueryRef(flat);
 
@@ -3007,18 +2969,16 @@ nsStandardURL::SetRef(const nsACString &
     mPath.mLen += shift;
     mRef.mLen = refLen;
     return NS_OK;
 }
 
 nsresult
 nsStandardURL::SetFileNameInternal(const nsACString &input)
 {
-    ENSURE_MUTABLE();
-
     const nsPromiseFlatCString &flat = PromiseFlatCString(input);
     const char *filename = flat.get();
 
     LOG(("nsStandardURL::SetFileNameInternal [filename=%s]\n", filename));
 
     if (mPath.mLen < 0)
         return SetPathQueryRef(flat);
 
@@ -3191,18 +3151,16 @@ nsStandardURL::GetFile(nsIFile **result)
     // behaving themselves, we'll stay on the safe side and clone the file.
     // see bug 212724 about fixing the consumers.
     return mFile->Clone(result);
 }
 
 nsresult
 nsStandardURL::SetFile(nsIFile *file)
 {
-    ENSURE_MUTABLE();
-
     NS_ENSURE_ARG_POINTER(file);
 
     nsresult rv;
     nsAutoCString url;
 
     rv = net_GetURLSpecFromFile(file, url);
     if (NS_FAILED(rv)) return rv;
 
@@ -3234,18 +3192,16 @@ nsStandardURL::SetFile(nsIFile *file)
 
 nsresult
 nsStandardURL::Init(uint32_t urlType,
                     int32_t defaultPort,
                     const nsACString &spec,
                     const char *charset,
                     nsIURI *baseURI)
 {
-    ENSURE_MUTABLE();
-
     if (spec.Length() > (uint32_t) net_GetURLMaxLength() ||
         defaultPort > std::numeric_limits<uint16_t>::max()) {
         return NS_ERROR_MALFORMED_URI;
     }
 
     InvalidateCache();
 
     switch (urlType) {
@@ -3287,18 +3243,16 @@ nsStandardURL::Init(uint32_t urlType,
     if (NS_FAILED(rv)) return rv;
 
     return SetSpecWithEncoding(buf, encoding);
 }
 
 nsresult
 nsStandardURL::SetDefaultPort(int32_t aNewDefaultPort)
 {
-    ENSURE_MUTABLE();
-
     InvalidateCache();
 
     // should never be more than 16 bit
     if (aNewDefaultPort >= std::numeric_limits<uint16_t>::max()) {
         return NS_ERROR_MALFORMED_URI;
     }
 
     // If we're already using the new default-port as a custom port, then clear
@@ -3308,32 +3262,16 @@ nsStandardURL::SetDefaultPort(int32_t aN
         ReplacePortInSpec(-1);
         mPort = -1;
     }
     mDefaultPort = aNewDefaultPort;
 
     return NS_OK;
 }
 
-NS_IMETHODIMP
-nsStandardURL::GetMutable(bool *value)
-{
-    *value = mMutable;
-    return NS_OK;
-}
-
-NS_IMETHODIMP
-nsStandardURL::SetMutable(bool value)
-{
-    NS_ENSURE_ARG(mMutable || !value);
-
-    mMutable = value;
-    return NS_OK;
-}
-
 //----------------------------------------------------------------------------
 // nsStandardURL::nsISerializable
 //----------------------------------------------------------------------------
 
 NS_IMETHODIMP
 nsStandardURL::Read(nsIObjectInputStream *stream)
 {
     NS_NOTREACHED("Use nsIURIMutator.read() instead");
@@ -3418,17 +3356,17 @@ nsStandardURL::ReadPrivate(nsIObjectInpu
 
     nsAutoCString oldOriginCharset;
     rv = NS_ReadOptionalCString(stream, oldOriginCharset);
     if (NS_FAILED(rv)) return rv;
 
     bool isMutable;
     rv = stream->ReadBoolean(&isMutable);
     if (NS_FAILED(rv)) return rv;
-    mMutable = isMutable;
+    Unused << isMutable;
 
     bool supportsFileURL;
     rv = stream->ReadBoolean(&supportsFileURL);
     if (NS_FAILED(rv)) return rv;
     mSupportsFileURL = supportsFileURL;
 
     // wait until object is set up, then modify path to include the param
     if (old_param.mLen >= 0) {  // note that mLen=0 is ";"
@@ -3512,17 +3450,18 @@ nsStandardURL::Write(nsIObjectOutputStre
 
     rv = WriteSegment(stream, mRef);
     if (NS_FAILED(rv)) return rv;
 
     // former origin charset
     rv = NS_WriteOptionalStringZ(stream, EmptyCString().get());
     if (NS_FAILED(rv)) return rv;
 
-    rv = stream->WriteBoolean(mMutable);
+    // former mMutable
+    rv = stream->WriteBoolean(false);
     if (NS_FAILED(rv)) return rv;
 
     rv = stream->WriteBoolean(mSupportsFileURL);
     if (NS_FAILED(rv)) return rv;
 
     // mDisplayHost is just a cache that can be recovered as needed.
 
     return NS_OK;
@@ -3583,17 +3522,16 @@ nsStandardURL::Serialize(URIParams& aPar
     params.host() = ToIPCSegment(mHost);
     params.path() = ToIPCSegment(mPath);
     params.filePath() = ToIPCSegment(mFilepath);
     params.directory() = ToIPCSegment(mDirectory);
     params.baseName() = ToIPCSegment(mBasename);
     params.extension() = ToIPCSegment(mExtension);
     params.query() = ToIPCSegment(mQuery);
     params.ref() = ToIPCSegment(mRef);
-    params.isMutable() = !!mMutable;
     params.supportsFileURL() = !!mSupportsFileURL;
     // mDisplayHost is just a cache that can be recovered as needed.
 
     aParams = params;
 }
 
 bool
 nsStandardURL::Deserialize(const URIParams& aParams)
@@ -3636,17 +3574,16 @@ nsStandardURL::Deserialize(const URIPara
     NS_ENSURE_TRUE(FromIPCSegment(mSpec, params.path(), mPath), false);
     NS_ENSURE_TRUE(FromIPCSegment(mSpec, params.filePath(), mFilepath), false);
     NS_ENSURE_TRUE(FromIPCSegment(mSpec, params.directory(), mDirectory), false);
     NS_ENSURE_TRUE(FromIPCSegment(mSpec, params.baseName(), mBasename), false);
     NS_ENSURE_TRUE(FromIPCSegment(mSpec, params.extension(), mExtension), false);
     NS_ENSURE_TRUE(FromIPCSegment(mSpec, params.query(), mQuery), false);
     NS_ENSURE_TRUE(FromIPCSegment(mSpec, params.ref(), mRef), false);
 
-    mMutable = params.isMutable();
     mSupportsFileURL = params.supportsFileURL();
 
     nsresult rv = CheckIfHostIsAscii();
     if (NS_FAILED(rv)) {
         return false;
     }
 
     // Some sanity checks
--- a/netwerk/base/nsStandardURL.h
+++ b/netwerk/base/nsStandardURL.h
@@ -60,17 +60,16 @@ protected:
 public:
     NS_DECL_THREADSAFE_ISUPPORTS
     NS_DECL_NSIURI
     NS_DECL_NSIURL
     NS_DECL_NSIFILEURL
     NS_DECL_NSISTANDARDURL
     NS_DECL_NSISERIALIZABLE
     NS_DECL_NSICLASSINFO
-    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;
 
     static void InitGlobalObjects();
@@ -295,17 +294,16 @@ private:
 
     enum {
         eEncoding_Unknown,
         eEncoding_ASCII,
         eEncoding_UTF8
     };
 
     uint32_t mURLType         : 2; // nsIStandardURL::URLTYPE_xxx
-    uint32_t mMutable         : 1; // nsIStandardURL::mutable
     uint32_t mSupportsFileURL : 1; // QI to nsIFileURL?
     uint32_t mCheckedIfHostA  : 1; // If set to true, it means either that
                                    // mDisplayHost has a been initialized, or
                                    // that the hostname is not punycode
 
     // global objects.  don't use COMPtr as its destructor will cause a
     // coredump if we leak it.
     static nsIIDNService               *gIDN;
--- a/netwerk/protocol/about/nsAboutProtocolHandler.cpp
+++ b/netwerk/protocol/about/nsAboutProtocolHandler.cpp
@@ -155,19 +155,16 @@ nsAboutProtocolHandler::NewURI(const nsA
         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);
     url.swap(*result);
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsAboutProtocolHandler::NewChannel2(nsIURI* uri,
                                     nsILoadInfo* aLoadInfo,
                                     nsIChannel** result)
@@ -320,17 +317,16 @@ nsSafeAboutProtocolHandler::NewURI(const
 {
     nsresult rv = NS_MutateURI(new nsSimpleURI::Mutator())
                     .SetSpec(aSpec)
                     .Finalize(result);
     if (NS_FAILED(rv)) {
         return rv;
     }
 
-    NS_TryToSetImmutable(*result);
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsSafeAboutProtocolHandler::NewChannel2(nsIURI* uri,
                                         nsILoadInfo* aLoadInfo,
                                         nsIChannel** result)
 {
@@ -439,17 +435,16 @@ nsNestedAboutURI::StartClone(nsSimpleURI
     }
 
     if (NS_FAILED(rv)) {
         return nullptr;
     }
 
     nsNestedAboutURI* url = new nsNestedAboutURI(innerClone, mBaseURI);
     SetRefOnClone(url, aRefHandlingMode, aNewRef);
-    url->SetMutable(false);
 
     return url;
 }
 
 // Queries this list of interfaces. If none match, it queries mURI.
 NS_IMPL_NSIURIMUTATOR_ISUPPORTS(nsNestedAboutURI::Mutator,
                                 nsIURISetters,
                                 nsIURIMutator,
@@ -459,19 +454,16 @@ NS_IMPL_NSIURIMUTATOR_ISUPPORTS(nsNested
 NS_IMETHODIMP
 nsNestedAboutURI::Mutate(nsIURIMutator** aMutator)
 {
     RefPtr<nsNestedAboutURI::Mutator> mutator = new nsNestedAboutURI::Mutator();
     nsresult rv = mutator->InitFromURI(this);
     if (NS_FAILED(rv)) {
         return rv;
     }
-    // StartClone calls SetMutable(false) but we need the mutator clone
-    // to be mutable
-    mutator->ResetMutable();
     mutator.forget(aMutator);
     return NS_OK;
 }
 
 // nsIClassInfo
 NS_IMETHODIMP
 nsNestedAboutURI::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc)
 {
--- a/netwerk/protocol/viewsource/nsViewSourceHandler.cpp
+++ b/netwerk/protocol/viewsource/nsViewSourceHandler.cpp
@@ -100,20 +100,16 @@ nsViewSourceHandler::NewURI(const nsACSt
     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.
-    NS_TryToSetImmutable(uri);
-
     uri.swap(*aResult);
     return rv;
 }
 
 NS_IMETHODIMP
 nsViewSourceHandler::NewChannel2(nsIURI* uri,
                                  nsILoadInfo* aLoadInfo,
                                  nsIChannel** result)
--- a/netwerk/test/unit/test_1351443-missing-NewChannel2.js
+++ b/netwerk/test/unit/test_1351443-missing-NewChannel2.js
@@ -12,17 +12,16 @@ ChromeUtils.import("resource://gre/modul
 var contentSecManager = Cc["@mozilla.org/contentsecuritymanager;1"]
                           .getService(Ci.nsIContentSecurityManager);
 
 function ProtocolHandler() {
   this.uri = Cc["@mozilla.org/network/simple-uri-mutator;1"]
                .createInstance(Ci.nsIURIMutator)
                .setSpec(this.scheme + ":dummy")
                .finalize();
-  this.uri.QueryInterface(Ci.nsIMutable).mutable = false;
 }
 
 ProtocolHandler.prototype = {
   /** nsIProtocolHandler */
   get scheme() {
     return "x-1351443";
   },
   get defaultPort() {
--- a/netwerk/test/unit/test_bug894586.js
+++ b/netwerk/test/unit/test_bug894586.js
@@ -10,17 +10,16 @@ ChromeUtils.import("resource://gre/modul
 var contentSecManager = Cc["@mozilla.org/contentsecuritymanager;1"]
                           .getService(Ci.nsIContentSecurityManager);
 
 function ProtocolHandler() {
   this.uri = Cc["@mozilla.org/network/simple-uri-mutator;1"]
                .createInstance(Ci.nsIURIMutator)
                .setSpec(this.scheme + ":dummy")
                .finalize();
-  this.uri.QueryInterface(Ci.nsIMutable).mutable = false;
 }
 
 ProtocolHandler.prototype = {
   /** nsIProtocolHandler */
   get scheme() {
     return "x-bug894586";
   },
   get defaultPort() {