Bug 1361975 window.location is not nullable, r=bz
authorAndrea Marchesini <amarchesini@mozilla.com>
Mon, 08 May 2017 15:49:08 +0200
changeset 357096 79890abc6ff5b948d3508739a13d2064952fa40d
parent 357095 b99cdf171a9b0f01b3018266d656af50d5273d2d
child 357097 9e2bc7a6959b2b9de8bfec2370c66e1d3a6d0cdc
push id31782
push userkwierso@gmail.com
push dateMon, 08 May 2017 23:07:35 +0000
treeherdermozilla-central@b21b974d60d3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs1361975
milestone55.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 1361975 window.location is not nullable, r=bz This patch adds a check on mDocShell in order to do not throw exceptions when Location is used with a null mDocShell. This is needed because the location object is not nullable anymore and it can be used also when the window is not connected to a docshell.
dom/base/Location.cpp
dom/base/Location.h
dom/base/nsGlobalWindow.cpp
dom/webidl/Window.webidl
--- a/dom/base/Location.cpp
+++ b/dom/base/Location.cpp
@@ -82,29 +82,16 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mInnerWindow)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(Location)
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(Location)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(Location)
 
-void
-Location::SetDocShell(nsIDocShell *aDocShell)
-{
-   mDocShell = do_GetWeakReference(aDocShell);
-}
-
-nsIDocShell *
-Location::GetDocShell()
-{
-  nsCOMPtr<nsIDocShell> docshell(do_QueryReferent(mDocShell));
-  return docshell;
-}
-
 nsresult
 Location::CheckURL(nsIURI* aURI, nsIDocShellLoadInfo** aLoadInfo)
 {
   *aLoadInfo = nullptr;
 
   nsCOMPtr<nsIDocShell> docShell(do_QueryReferent(mDocShell));
   NS_ENSURE_TRUE(docShell, NS_ERROR_NOT_AVAILABLE);
 
@@ -205,18 +192,22 @@ Location::CheckURL(nsIURI* aURI, nsIDocS
   return NS_OK;
 }
 
 nsresult
 Location::GetURI(nsIURI** aURI, bool aGetInnermostURI)
 {
   *aURI = nullptr;
 
+  nsCOMPtr<nsIDocShell> docShell(do_QueryReferent(mDocShell));
+  if (!mDocShell) {
+    return NS_OK;
+  }
+
   nsresult rv;
-  nsCOMPtr<nsIDocShell> docShell(do_QueryReferent(mDocShell));
   nsCOMPtr<nsIWebNavigation> webNav(do_QueryInterface(docShell, &rv));
   if (NS_FAILED(rv)) {
     return rv;
   }
 
   nsCOMPtr<nsIURI> uri;
   rv = webNav->GetCurrentURI(getter_AddRefs(uri));
   NS_ENSURE_SUCCESS(rv, rv);
@@ -891,19 +882,20 @@ Location::GetSourceBaseURL(JSContext* cx
   *sourceURL = nullptr;
   nsIDocument* doc = GetEntryDocument();
   // If there's no entry document, we either have no Script Entry Point or one
   // that isn't a DOM Window.  This doesn't generally happen with the DOM, but
   // can sometimes happen with extension code in certain IPC configurations.  If
   // this happens, try falling back on the current document associated with the
   // docshell. If that fails, just return null and hope that the caller passed
   // an absolute URI.
-  if (!doc && GetDocShell()) {
+  nsCOMPtr<nsIDocShell> docShell(do_QueryReferent(mDocShell));
+  if (!doc && docShell) {
     nsCOMPtr<nsPIDOMWindowOuter> docShellWin =
-      do_QueryInterface(GetDocShell()->GetScriptGlobalObject());
+      do_QueryInterface(docShell->GetScriptGlobalObject());
     if (docShellWin) {
       doc = docShellWin->GetDoc();
     }
   }
   NS_ENSURE_TRUE(doc, NS_OK);
   *sourceURL = doc->GetBaseURI().take();
   return NS_OK;
 }
--- a/dom/base/Location.h
+++ b/dom/base/Location.h
@@ -32,19 +32,16 @@ class Location final : public nsIDOMLoca
 {
 public:
   Location(nsPIDOMWindowInner* aWindow, nsIDocShell *aDocShell);
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(Location,
                                                          nsIDOMLocation)
 
-  void SetDocShell(nsIDocShell *aDocShell);
-  nsIDocShell *GetDocShell();
-
   // nsIDOMLocation
   NS_DECL_NSIDOMLOCATION
 
   #define THROW_AND_RETURN_IF_CALLER_DOESNT_SUBSUME() { \
     if (!CallerSubsumes(&aSubjectPrincipal)) { \
       aError.Throw(NS_ERROR_DOM_SECURITY_ERR); \
       return; \
     } \
@@ -228,17 +225,21 @@ public:
 protected:
   virtual ~Location();
 
   nsresult SetSearchInternal(const nsAString& aSearch);
 
   // In the case of jar: uris, we sometimes want the place the jar was
   // fetched from as the URI instead of the jar: uri itself.  Pass in
   // true for aGetInnermostURI when that's the case.
+  // Note, this method can return NS_OK with a null value for aURL. This happens
+  // if the docShell is null.
   nsresult GetURI(nsIURI** aURL, bool aGetInnermostURI = false);
+  // Note, this method can return NS_OK with a null value for aURL. This happens
+  // if the docShell is null.
   nsresult GetWritableURI(nsIURI** aURL,
                           // If not null, give it the new ref
                           const nsACString* aNewRef = nullptr);
   nsresult SetURI(nsIURI* aURL, bool aReplace = false);
   nsresult SetHrefWithBase(const nsAString& aHref, nsIURI* aBase,
                            bool aReplace);
   nsresult SetHrefWithContext(JSContext* cx, const nsAString& aHref,
                               bool aReplace);
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -1928,17 +1928,16 @@ nsGlobalWindow::CleanUp()
 
   mScreen = nullptr;
   mMenubar = nullptr;
   mToolbar = nullptr;
   mLocationbar = nullptr;
   mPersonalbar = nullptr;
   mStatusbar = nullptr;
   mScrollbars = nullptr;
-  mLocation = nullptr;
   mHistory = nullptr;
   mCustomElements = nullptr;
   mFrames = nullptr;
   mWindowUtils = nullptr;
   mApplicationCache = nullptr;
   mIndexedDB = nullptr;
 
   mConsole = nullptr;
@@ -2091,17 +2090,16 @@ nsGlobalWindow::FreeInnerObjects()
 
   mChromeEventHandler = nullptr;
 
   if (mListenerManager) {
     mListenerManager->Disconnect();
     mListenerManager = nullptr;
   }
 
-  mLocation = nullptr;
   mHistory = nullptr;
   mCustomElements = nullptr;
 
   if (mNavigator) {
     mNavigator->OnNavigation();
     mNavigator->Invalidate();
     mNavigator = nullptr;
   }
@@ -10439,20 +10437,20 @@ nsGlobalWindow::GetPrivateRoot()
   return top;
 }
 
 Location*
 nsGlobalWindow::GetLocation(ErrorResult& aError)
 {
   MOZ_RELEASE_ASSERT(IsInnerWindow());
 
-  nsIDocShell *docShell = GetDocShell();
-  if (!mLocation && docShell) {
-    mLocation = new Location(AsInner(), docShell);
-  }
+  if (!mLocation) {
+    mLocation = new Location(AsInner(), GetDocShell());
+  }
+
   return mLocation;
 }
 
 nsIDOMLocation*
 nsGlobalWindow::GetLocation()
 {
   FORWARD_TO_INNER(GetLocation, (), nullptr);
 
--- a/dom/webidl/Window.webidl
+++ b/dom/webidl/Window.webidl
@@ -31,17 +31,17 @@ interface nsIDOMCrypto;
   // the current browsing context
   [Unforgeable, Constant, StoreInSlot,
    CrossOriginReadable] readonly attribute Window window;
   [Replaceable, Constant, StoreInSlot,
    CrossOriginReadable] readonly attribute Window self;
   [Unforgeable, StoreInSlot, Pure] readonly attribute Document? document;
   [Throws] attribute DOMString name;
   [PutForwards=href, Unforgeable, Throws,
-   CrossOriginReadable, CrossOriginWritable] readonly attribute Location? location;
+   CrossOriginReadable, CrossOriginWritable] readonly attribute Location location;
   [Throws] readonly attribute History history;
   [Func="CustomElementRegistry::IsCustomElementEnabled"]
   readonly attribute CustomElementRegistry customElements;
   [Replaceable, Throws] readonly attribute BarProp locationbar;
   [Replaceable, Throws] readonly attribute BarProp menubar;
   [Replaceable, Throws] readonly attribute BarProp personalbar;
   [Replaceable, Throws] readonly attribute BarProp scrollbars;
   [Replaceable, Throws] readonly attribute BarProp statusbar;