Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Corrupted commit while pulling central this morning #214

Closed
emilio opened this issue Apr 25, 2019 · 8 comments
Closed

Corrupted commit while pulling central this morning #214

emilio opened this issue Apr 25, 2019 · 8 comments

Comments

@emilio
Copy link

emilio commented Apr 25, 2019

So I pulled central today, as I do most days, and I cannot build because a file in my repo is corrupted.

The file is dom/ipc/BrowserParent.cpp, which has a bad modeline and a few other borked changes.

According to git blame, this is the commit that introduced the issue:

commit b4deb8f0be6053c369efc94ffca73e446eced889
Author: Ehsan Akhgari <[email protected]>
Date:   Wed Apr 24 23:50:40 2019 +0000

    Bug 1527287 - Add support for "noreferrer" feature argument to window.open(); r=qdot
    
    Differential Revision: https://phabricator.services.mozilla.com/D28396

diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js
index 20b245876b78..593e6607a746 100644
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -5749,8 +5749,13 @@ nsBrowserAccess.prototype = {
         aWhere = Services.prefs.getIntPref("browser.link.open_newwindow");
     }
 
-    let referrerInfo = new ReferrerInfo(Ci.nsIHttpChannel.REFERRER_POLICY_UNSET, true,
-      aOpener ? makeURI(aOpener.location.href) : null);
+    let referrerInfo;
+    if (aFlags & Ci.nsIBrowserDOMWindow.OPEN_NO_REFERRER) {
+      referrerInfo = new ReferrerInfo(Ci.nsIHttpChannel.REFERRER_POLICY_UNSET, false, null);
+    } else {
+      referrerInfo = new ReferrerInfo(Ci.nsIHttpChannel.REFERRER_POLICY_UNSET, true,
+        aOpener ? makeURI(aOpener.location.href) : null);
+    }
     if (aOpener && aOpener.document) {
       referrerInfo.referrerPolicy = aOpener.document.referrerPolicy;
     }
diff --git a/devtools/client/responsive.html/browser/tunnel.js b/devtools/client/responsive.html/browser/tunnel.js
index 4deae1c75057..ac0898c0ffbe 100644
--- a/devtools/client/responsive.html/browser/tunnel.js
+++ b/devtools/client/responsive.html/browser/tunnel.js
@@ -263,13 +263,16 @@ function tunnelToInnerBrowser(outer, inner) {
       const { detail } = event;
       event.preventDefault();
       const uri = Services.io.newURI(detail.url);
+      let flags = Ci.nsIBrowserDOMWindow.OPEN_NEWTAB;
+      if (detail.forceNoReferrer) {
+        flags |= Ci.nsIBrowserDOMWindow.OPEN_NO_REFERRER;
+      }
       // This API is used mainly because it's near the path used for <a target/> with
       // regular browser tabs (which calls `openURIInFrame`).  The more elaborate APIs
       // that support openers, window features, etc. didn't seem callable from JS and / or
       // this event doesn't give enough info to use them.
       browserWindow.browserDOMWindow
-        .openURI(uri, null, Ci.nsIBrowserDOMWindow.OPEN_NEWTAB,
-                 Ci.nsIBrowserDOMWindow.OPEN_NEW,
+        .openURI(uri, null, flags, Ci.nsIBrowserDOMWindow.OPEN_NEW,
                  outer.contentPrincipal);
     },
 
diff --git a/dom/base/nsGlobalWindowOuter.cpp b/dom/base/nsGlobalWindowOuter.cpp
index 02414bfda897..95e07592388b 100644
--- a/dom/base/nsGlobalWindowOuter.cpp
+++ b/dom/base/nsGlobalWindowOuter.cpp
@@ -7071,6 +7071,7 @@ nsresult nsGlobalWindowOuter::OpenInternal(
 
   nsAutoCString options;
   bool forceNoOpener = aForceNoOpener;
+  bool forceNoReferrer = false;
   // Unlike other window flags, "noopener" comes from splitting on commas with
   // HTML whitespace trimming...
   nsCharSeparatedTokenizerTemplate<nsContentUtils::IsHTMLWhitespace> tok(
@@ -7081,6 +7082,13 @@ nsresult nsGlobalWindowOuter::OpenInternal(
       forceNoOpener = true;
       continue;
     }
+    if (StaticPrefs::dom_window_open_noreferrer_enabled() &&
+        nextTok.LowerCaseEqualsLiteral("noreferrer")) {
+      forceNoReferrer = true;
+      // noreferrer implies noopener
+      forceNoOpener = true;
+      continue;
+    }
     // Want to create a copy of the options without 'noopener' because having
     // 'noopener' in the options affects other window features.
     if (!options.IsEmpty()) {
@@ -7186,7 +7194,7 @@ nsresult nsGlobalWindowOuter::OpenInternal(
       rv = pwwatch->OpenWindow2(
           this, url.IsVoid() ? nullptr : url.get(), name_ptr, options_ptr,
           /* aCalledFromScript = */ true, aDialog, aNavigate, argv,
-          isPopupSpamWindow, forceNoOpener, aLoadState,
+          isPopupSpamWindow, forceNoOpener, forceNoReferrer, aLoadState,
           getter_AddRefs(domReturn));
     } else {
       // Force a system caller here so that the window watcher won't screw us
@@ -7206,7 +7214,7 @@ nsresult nsGlobalWindowOuter::OpenInternal(
       rv = pwwatch->OpenWindow2(
           this, url.IsVoid() ? nullptr : url.get(), name_ptr, options_ptr,
           /* aCalledFromScript = */ false, aDialog, aNavigate, aExtraArgument,
-          isPopupSpamWindow, forceNoOpener, aLoadState,
+          isPopupSpamWindow, forceNoOpener, forceNoReferrer, aLoadState,
           getter_AddRefs(domReturn));
     }
   }
diff --git a/dom/browser-element/BrowserElementParent.cpp b/dom/browser-element/BrowserElementParent.cpp
index e1435f539b51..7c98651de5b0 100644
--- a/dom/browser-element/BrowserElementParent.cpp
+++ b/dom/browser-element/BrowserElementParent.cpp
@@ -114,6 +114,7 @@ BrowserElementParent::DispatchOpenWindowEvent(Element* aOpenerFrameElement,
                                               Element* aPopupFrameElement,
                                               const nsAString& aURL,
                                               const nsAString& aName,
+                                              bool aForceNoReferrer,
                                               const nsAString& aFeatures) {
   // Dispatch a CustomEvent at aOpenerFrameElement with a detail object
   // (OpenWindowEventDetail) containing aPopupFrameElement, aURL, aName, and
@@ -130,6 +131,7 @@ BrowserElementParent::DispatchOpenWindowEvent(Element* aOpenerFrameElement,
   detail.mName = aName;
   detail.mFeatures = aFeatures;
   detail.mFrameElement = aPopupFrameElement;
+  detail.mForceNoReferrer = aForceNoReferrer;
 
   nsIGlobalObject* sgo = aPopupFrameElement->OwnerDoc()->GetScopeObject();
   if (!sgo) {
@@ -172,8 +174,9 @@ BrowserElementParent::DispatchOpenWindowEvent(Element* aOpenerFrameElement,
 
 /*static*/
 BrowserElementParent::OpenWindowResult BrowserElementParent::OpenWindowOOP(
-    BrowserParent* aOpenerBrowserParent, BrowserParent* aPopupBrowserParent,
-    const nsAString& aURL, const nsAString& aName, const nsAString& aFeatures) {
+    BrowserParent* aOpenerTabParent, BrowserParent* aPopupTabParent,
+    const nsAString& aURL, const nsAString& aName, bool aForceNoReferrer,
+    const nsAString& aFeatures) {
   // Create an iframe owned by the same document which owns openerFrameElement.
   nsCOMPtr<Element> openerFrameElement =
       aOpenerBrowserParent->GetOwnerElement();
@@ -193,8 +196,9 @@ BrowserElementParent::OpenWindowResult BrowserElementParent::OpenWindowOOP(
   // allowed.
   popupFrameElement->DisallowCreateFrameLoader();
 
-  OpenWindowResult opened = DispatchOpenWindowEvent(
-      openerFrameElement, popupFrameElement, aURL, aName, aFeatures);
+  OpenWindowResult opened =
+      DispatchOpenWindowEvent(openerFrameElement, popupFrameElement, aURL,
+                              aName, aForceNoReferrer, aFeatures);
 
   if (opened != BrowserElementParent::OPEN_WINDOW_ADDED) {
     return opened;
@@ -250,7 +254,7 @@ BrowserElementParent::OpenWindowInProcess(BrowsingContext* aOpenerWindow,
 
   OpenWindowResult opened = DispatchOpenWindowEvent(
       openerFrameElement, popupFrameElement, NS_ConvertUTF8toUTF16(spec), aName,
-      NS_ConvertUTF8toUTF16(aFeatures));
+      false, NS_ConvertUTF8toUTF16(aFeatures));
 
   if (opened != BrowserElementParent::OPEN_WINDOW_ADDED) {
     return opened;
diff --git a/dom/browser-element/BrowserElementParent.h b/dom/browser-element/BrowserElementParent.h
index de63c381049e..131910805e5b 100644
--- a/dom/browser-element/BrowserElementParent.h
+++ b/dom/browser-element/BrowserElementParent.h
@@ -87,10 +87,12 @@ class BrowserElementParent {
    *         frame to a document and whether it called preventDefault to prevent
    *         the platform from handling the open request.
    */
-  static OpenWindowResult OpenWindowOOP(
-      dom::BrowserParent* aOpenerBrowserParent,
-      dom::BrowserParent* aPopupBrowserParent, const nsAString& aURL,
-      const nsAString& aName, const nsAString& aFeatures);
+  static OpenWindowResult OpenWindowOOP(dom::BrowserParent* aOpenerTabParent,
+                                        dom::BrowserParent* aPopupTabParent,
+                                        const nsAString& aURL,
+                                        const nsAString& aName,
+                                        bool aForceNoReferrer,
+                                        const nsAString& aFeatures);
 
   /**
    * Handle a window.open call from an in-process <iframe mozbrowser>.
@@ -111,7 +113,7 @@ class BrowserElementParent {
  private:
   static OpenWindowResult DispatchOpenWindowEvent(
       dom::Element* aOpenerFrameElement, dom::Element* aPopupFrameElement,
-      const nsAString& aURL, const nsAString& aName,
+      const nsAString& aURL, const nsAString& aName, bool aForceNoReferrer,
       const nsAString& aFeatures);
 };
 
diff --git a/dom/clients/manager/ClientOpenWindowUtils.cpp b/dom/clients/manager/ClientOpenWindowUtils.cpp
index d97e00481681..1ffab908772f 100644
--- a/dom/clients/manager/ClientOpenWindowUtils.cpp
+++ b/dom/clients/manager/ClientOpenWindowUtils.cpp
@@ -241,6 +241,7 @@ nsresult OpenWindow(const ClientOpenWindowArgs& aArgs,
         // opener anyway, and we _do_ want the returned
         // window.
         /* aForceNoOpener = */ false,
+        /* aForceNoReferrer = */ false,
         /* aLoadInfp = */ nullptr, getter_AddRefs(newWindow));
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
diff --git a/dom/interfaces/base/nsIBrowserDOMWindow.idl b/dom/interfaces/base/nsIBrowserDOMWindow.idl
index 99907f6c9360..76dbda700a50 100644
--- a/dom/interfaces/base/nsIBrowserDOMWindow.idl
+++ b/dom/interfaces/base/nsIBrowserDOMWindow.idl
@@ -95,6 +95,12 @@ interface nsIBrowserDOMWindow : nsISupports
    */
   const long OPEN_NO_OPENER     = 0x4;
 
+  /**
+   * Don't set the referrer on the navigation inside the window which is
+   * being opened.
+   */
+  const long OPEN_NO_REFERRER   = 0x8;
+
   /**
    * Create the content window for the given URI.
 
diff --git a/dom/ipc/BrowserChild.cpp b/dom/ipc/BrowserChild.cpp
index c873cce4051c..3eba6c61905d 100644
--- a/dom/ipc/BrowserChild.cpp
+++ b/dom/ipc/BrowserChild.cpp
@@ -908,7 +908,7 @@ BrowserChild::ProvideWindow(mozIDOMWindowProxy* aParent, uint32_t aChromeFlags,
                             bool aCalledFromJS, bool aPositionSpecified,
                             bool aSizeSpecified, nsIURI* aURI,
                             const nsAString& aName, const nsACString& aFeatures,
-                            bool aForceNoOpener,
+                            bool aForceNoOpener, bool aForceNoReferrer,
                             nsDocShellLoadState* aLoadState, bool* aWindowIsNew,
                             mozIDOMWindowProxy** aReturn) {
   *aReturn = nullptr;
@@ -943,8 +943,8 @@ BrowserChild::ProvideWindow(mozIDOMWindowProxy* aParent, uint32_t aChromeFlags,
   ContentChild* cc = ContentChild::GetSingleton();
   return cc->ProvideWindowCommon(
       this, aParent, iframeMoz, aChromeFlags, aCalledFromJS, aPositionSpecified,
-      aSizeSpecified, aURI, aName, aFeatures, aForceNoOpener, aLoadState,
-      aWindowIsNew, aReturn);
+      aSizeSpecified, aURI, aName, aFeatures, aForceNoOpener, aForceNoReferrer,
+      aLoadState, aWindowIsNew, aReturn);
 }
 
 void BrowserChild::DestroyWindow() {
diff --git a/dom/ipc/BrowserParent.cpp b/dom/ipc/BrowserParent.cpp
index 33fcbdb435a5..02ced5130590 100644
--- a/dom/ipc/BrowserParent.cpp
+++ b/dom/ipc/BrowserParent.cpp
@@ -1,5 +1,4 @@
-/* -*- Mode: C++; tab-width: 8copyrev: 1ec0be325e6d41111f155363bf6c6ccfb640c610
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+ vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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/. */
@@ -2884,15 +2883,14 @@ void BrowserParent::ApzAwareEventRoutingToChild(
 mozilla::ipc::IPCResult BrowserParent::RecvBrowserFrameOpenWindow(
     PBrowserParent* aOpener, const nsString& aURL, const nsString& aName,
     const nsString& aFeatures, BrowserFrameOpenWindowResolver&& aResolve) {
-  CreatedWindowInfo cwi;
-  cwi.rv() = NS_OK;
-  cwi.maxTouchPoints() = 0;
-
-  BrowserElementParent::OpenWindowResult opened =
+  Crea    bool aForceNoReferrer, const nsString& aFeatures,
+    BrowserFrameOpenWindowResolver&& aResolve) {
+rElementParent::OpenWindowResult opened =
       BrowserElementParent::OpenWindowOOP(BrowserParent::GetFrom(aOpener), this,
                                           aURL, aName, aFeatures);
-  cwi.windowOpened() = (opened == BrowserElementParent::OPEN_WINDOW_ADDED);
-  nsCOMPtr<nsIWidget> widget = GetWidget();
+  cwi.windowOpe                                          aURL, aName, aForceNoReferrer,
+                                          aFeatures);
+MPtr<nsIWidget> widget = GetWidget();
   if (widget) {
     cwi.maxTouchPoints() = widget->GetMaxTouchPoints();
     cwi.dimensions() = GetDimensionInfo();
diff --git a/dom/ipc/BrowserParent.h b/dom/ipc/BrowserParent.h
index 74da20e982dd..9416387dd7bf 100644
--- a/dom/ipc/BrowserParent.h
+++ b/dom/ipc/BrowserParent.h
@@ -193,7 +193,8 @@ class BrowserParent final : public PBrowserParent,
 
   mozilla::ipc::IPCResult RecvBrowserFrameOpenWindow(
       PBrowserParent* aOpener, const nsString& aURL, const nsString& aName,
-      const nsString& aFeatures, BrowserFrameOpenWindowResolver&& aResolve);
+      bool aForceNoReferrer, const nsString& aFeatures,
+      BrowserFrameOpenWindowResolver&& aResolve);
 
   mozilla::ipc::IPCResult RecvSyncMessage(
       const nsString& aMessage, const ClonedMessageData& aData,
diff --git a/dom/ipc/ContentChild.cpp b/dom/ipc/ContentChild.cpp
index b6a5438ee256..a64dcf712e1a 100644
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -754,18 +754,18 @@ ContentChild::ProvideWindow(mozIDOMWindowProxy* aParent, uint32_t aChromeFlags,
                             bool aCalledFromJS, bool aPositionSpecified,
                             bool aSizeSpecified, nsIURI* aURI,
                             const nsAString& aName, const nsACString& aFeatures,
-                            bool aForceNoOpener,
+                            bool aForceNoOpener, bool aForceNoReferrer,
                             nsDocShellLoadState* aLoadState, bool* aWindowIsNew,
                             mozIDOMWindowProxy** aReturn) {
-  return ProvideWindowCommon(nullptr, aParent, false, aChromeFlags,
-                             aCalledFromJS, aPositionSpecified, aSizeSpecified,
-                             aURI, aName, aFeatures, aForceNoOpener, aLoadState,
-                             aWindowIsNew, aReturn);
+  return ProvideWindowCommon(
+      nullptr, aParent, false, aChromeFlags, aCalledFromJS, aPositionSpecified,
+      aSizeSpecified, aURI, aName, aFeatures, aForceNoOpener, aForceNoReferrer,
+      aLoadState, aWindowIsNew, aReturn);
 }
 
 static nsresult GetCreateWindowParams(mozIDOMWindowProxy* aParent,
                                       nsDocShellLoadState* aLoadState,
-                                      float* aFullZoom,
+                                      bool aForceNoReferrer, float* aFullZoom,
                                       nsIReferrerInfo** aReferrerInfo,
                                       nsIPrincipal** aTriggeringPrincipal,
                                       nsIContentSecurityPolicy** aCsp) {
@@ -781,7 +781,11 @@ static nsresult GetCreateWindowParams(mozIDOMWindowProxy* aParent,
   }
 
   nsCOMPtr<nsIReferrerInfo> referrerInfo;
-  if (aLoadState) {
+  if (aForceNoReferrer) {
+    referrerInfo = new ReferrerInfo(
+        nullptr, mozilla::net::ReferrerPolicy::RP_Unset, false);
+  }
+  if (aLoadState && !referrerInfo) {
     referrerInfo = aLoadState->GetReferrerInfo();
   }
 
@@ -842,7 +846,7 @@ nsresult ContentChild::ProvideWindowCommon(
     BrowserChild* aTabOpener, mozIDOMWindowProxy* aParent, bool aIframeMoz,
     uint32_t aChromeFlags, bool aCalledFromJS, bool aPositionSpecified,
     bool aSizeSpecified, nsIURI* aURI, const nsAString& aName,
-    const nsACString& aFeatures, bool aForceNoOpener,
+    const nsACString& aFeatures, bool aForceNoOpener, bool aForceNoReferrer,
     nsDocShellLoadState* aLoadState, bool* aWindowIsNew,
     mozIDOMWindowProxy** aReturn) {
   *aReturn = nullptr;
@@ -888,9 +892,10 @@ nsresult ContentChild::ProvideWindowCommon(
     nsCOMPtr<nsIPrincipal> triggeringPrincipal;
     nsCOMPtr<nsIContentSecurityPolicy> csp;
     nsCOMPtr<nsIReferrerInfo> referrerInfo;
-    rv = GetCreateWindowParams(
-        aParent, aLoadState, &fullZoom, getter_AddRefs(referrerInfo),
-        getter_AddRefs(triggeringPrincipal), getter_AddRefs(csp));
+    rv = GetCreateWindowParams(aParent, aLoadState, aForceNoReferrer, &fullZoom,
+                               getter_AddRefs(referrerInfo),
+                               getter_AddRefs(triggeringPrincipal),
+                               getter_AddRefs(csp));
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
@@ -1106,17 +1111,18 @@ nsresult ContentChild::ProvideWindowCommon(
 
     // NOTE: BrowserFrameOpenWindowPromise is the same type as
     // CreateWindowPromise, and this code depends on that fact.
-    newChild->SendBrowserFrameOpenWindow(aTabOpener, NS_ConvertUTF8toUTF16(url),
-                                         name, NS_ConvertUTF8toUTF16(features),
-                                         std::move(resolve), std::move(reject));
+    newChild->SendBrowserFrameOpenWindow(
+        aTabOpener, NS_ConvertUTF8toUTF16(url), name, aForceNoReferrer,
+        NS_ConvertUTF8toUTF16(features), std::move(resolve), std::move(reject));
   } else {
     float fullZoom;
     nsCOMPtr<nsIPrincipal> triggeringPrincipal;
     nsCOMPtr<nsIContentSecurityPolicy> csp;
     nsCOMPtr<nsIReferrerInfo> referrerInfo;
-    rv = GetCreateWindowParams(
-        aParent, aLoadState, &fullZoom, getter_AddRefs(referrerInfo),
-        getter_AddRefs(triggeringPrincipal), getter_AddRefs(csp));
+    rv = GetCreateWindowParams(aParent, aLoadState, aForceNoReferrer, &fullZoom,
+                               getter_AddRefs(referrerInfo),
+                               getter_AddRefs(triggeringPrincipal),
+                               getter_AddRefs(csp));
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
diff --git a/dom/ipc/ContentChild.h b/dom/ipc/ContentChild.h
index 7e92670ea0b3..f886d072ef73 100644
--- a/dom/ipc/ContentChild.h
+++ b/dom/ipc/ContentChild.h
@@ -109,15 +109,13 @@ class ContentChild final : public PContentChild,
     nsCString sourceURL;
   };
 
-  nsresult ProvideWindowCommon(BrowserChild* aTabOpener,
-                               mozIDOMWindowProxy* aOpener, bool aIframeMoz,
-                               uint32_t aChromeFlags, bool aCalledFromJS,
-                               bool aPositionSpecified, bool aSizeSpecified,
-                               nsIURI* aURI, const nsAString& aName,
-                               const nsACString& aFeatures, bool aForceNoOpener,
-                               nsDocShellLoadState* aLoadState,
-                               bool* aWindowIsNew,
-                               mozIDOMWindowProxy** aReturn);
+  nsresult ProvideWindowCommon(
+      BrowserChild* aTabOpener, mozIDOMWindowProxy* aParent, bool aIframeMoz,
+      uint32_t aChromeFlags, bool aCalledFromJS, bool aPositionSpecified,
+      bool aSizeSpecified, nsIURI* aURI, const nsAString& aName,
+      const nsACString& aFeatures, bool aForceNoOpener, bool aForceNoReferrer,
+      nsDocShellLoadState* aLoadState, bool* aWindowIsNew,
+      mozIDOMWindowProxy** aReturn);
 
   bool Init(MessageLoop* aIOLoop, base::ProcessId aParentPid,
             const char* aParentBuildID, IPC::Channel* aChannel,
diff --git a/dom/ipc/PBrowser.ipdl b/dom/ipc/PBrowser.ipdl
index 89c0fa07d4e7..a763e555829c 100644
--- a/dom/ipc/PBrowser.ipdl
+++ b/dom/ipc/PBrowser.ipdl
@@ -454,7 +454,8 @@ parent:
      * @param opener the PBrowser whose content called window.open.
      */
     async BrowserFrameOpenWindow(PBrowser opener,
-                                 nsString aURL, nsString aName, nsString aFeatures)
+                                 nsString aURL, nsString aName,
+                                 bool aForceNoReferrer, nsString aFeatures)
         returns (CreatedWindowInfo window);
 
     /**
diff --git a/dom/tests/browser/browser_noopener.js b/dom/tests/browser/browser_noopener.js
index 7c9ce2216d2c..7f54dbca962a 100644
--- a/dom/tests/browser/browser_noopener.js
+++ b/dom/tests/browser/browser_noopener.js
@@ -10,11 +10,11 @@ const TESTS = [
 
   {id: "#test7", name: "", opener: true, newWindow: false},
   {id: "#test8", name: "", opener: false, newWindow: false},
-  {id: "#test9", name: "", opener: true, newWindow: true},
+  {id: "#test9", name: "", opener: false, newWindow: false},
 
   {id: "#test10", name: "uniquename1", opener: true, newWindow: false},
   {id: "#test11", name: "uniquename2", opener: false, newWindow: false},
-  {id: "#test12", name: "uniquename3", opener: true, newWindow: true},
+  {id: "#test12", name: "uniquename3", opener: false, newWindow: false},
 ];
 
 const TEST_URL = "http://mochi.test:8888/browser/dom/tests/browser/test_noopener_source.html";
@@ -99,6 +99,10 @@ async function doAllTests() {
 // constant starting and stopping processes, and opens a new window ~144 times.
 requestLongerTimeout(25);
 
+add_task(async function prepare() {
+  await SpecialPowers.pushPrefEnv({set: [["dom.window.open.noreferrer.enabled", true]]});
+});
+
 add_task(async function newtab_sameproc() {
   await SpecialPowers.pushPrefEnv({set: [[OPEN_NEWWINDOW_PREF, OPEN_NEWTAB],
                                          [NOOPENER_NEWPROC_PREF, false]]});
diff --git a/dom/webidl/BrowserElementDictionaries.webidl b/dom/webidl/BrowserElementDictionaries.webidl
index 400e402532c5..8b3f4f7e76be 100644
--- a/dom/webidl/BrowserElementDictionaries.webidl
+++ b/dom/webidl/BrowserElementDictionaries.webidl
@@ -12,6 +12,7 @@ dictionary OpenWindowEventDetail {
   DOMString name = "";
   DOMString features = "";
   Node? frameElement = null;
+  boolean forceNoReferrer = false;
 };
 
 dictionary DOMWindowResizeEventDetail {
diff --git a/mobile/android/chrome/content/browser.js b/mobile/android/chrome/content/browser.js
index c565ddaadf4a..0cecde56af30 100644
--- a/mobile/android/chrome/content/browser.js
+++ b/mobile/android/chrome/content/browser.js
@@ -3412,10 +3412,11 @@ nsBrowserAccess.prototype = {
     Services.io.offline = false;
 
     let referrer;
+    let forceNoReferrer = !!(aFlags & Ci.nsIBrowserDOMWindow.OPEN_NO_REFERRER);
     if (aOpener) {
       try {
         let location = aOpener.location;
-        referrer = Services.io.newURI(location);
+        referrer = forceNoReferrer ? null : Services.io.newURI(location);
       } catch(e) { }
     }
 
diff --git a/modules/libpref/init/StaticPrefList.h b/modules/libpref/init/StaticPrefList.h
index b082d69cc1bd..97e24b243703 100644
--- a/modules/libpref/init/StaticPrefList.h
+++ b/modules/libpref/init/StaticPrefList.h
@@ -590,6 +590,14 @@ VARCACHE_PREF(
   bool, true
 )
 
+// Enable the "noreferrer" feature argument for window.open()
+VARCACHE_PREF(
+  "dom.window.open.noreferrer.enabled",
+   dom_window_open_noreferrer_enabled,
+  bool, true
+)
+
+
 //---------------------------------------------------------------------------
 // Extension prefs
 //---------------------------------------------------------------------------
diff --git a/testing/web-platform/meta/html/browsers/the-window-object/window-open-noreferrer.html.ini b/testing/web-platform/meta/html/browsers/the-window-object/window-open-noreferrer.html.ini
deleted file mode 100644
index ba7f8d69f1de..000000000000
--- a/testing/web-platform/meta/html/browsers/the-window-object/window-open-noreferrer.html.ini
+++ /dev/null
@@ -1,4 +0,0 @@
-[window-open-noreferrer.html]
-  [window.open() with "noreferrer" tests]
-    expected: FAIL
-
diff --git a/toolkit/components/windowcreator/nsIWindowProvider.idl b/toolkit/components/windowcreator/nsIWindowProvider.idl
index 41b7e39a095d..f1231ee7612c 100644
--- a/toolkit/components/windowcreator/nsIWindowProvider.idl
+++ b/toolkit/components/windowcreator/nsIWindowProvider.idl
@@ -106,6 +106,7 @@ interface nsIWindowProvider : nsISupports
                                    in AString aName,
                                    in AUTF8String aFeatures,
                                    in boolean aForceNoOpener,
+                                   in boolean aForceNoReferrer,
                                    in nsDocShellLoadStatePtr aLoadState,
                                    out boolean aWindowIsNew);
 };
diff --git a/toolkit/components/windowwatcher/nsPIWindowWatcher.idl b/toolkit/components/windowwatcher/nsPIWindowWatcher.idl
index 9965e14c72d3..206add7807f5 100644
--- a/toolkit/components/windowwatcher/nsPIWindowWatcher.idl
+++ b/toolkit/components/windowwatcher/nsPIWindowWatcher.idl
@@ -89,6 +89,7 @@ interface nsPIWindowWatcher : nsISupports
                                  in nsISupports aArgs,
                                  in boolean aIsPopupSpam,
                                  in boolean aForceNoOpener,
+                                 in boolean aForceNoReferrer,
                                  in nsDocShellLoadStatePtr aLoadState);
 
   /**
diff --git a/toolkit/components/windowwatcher/nsWindowWatcher.cpp b/toolkit/components/windowwatcher/nsWindowWatcher.cpp
index 05d58d4c1a9e..30d8da663987 100644
--- a/toolkit/components/windowwatcher/nsWindowWatcher.cpp
+++ b/toolkit/components/windowwatcher/nsWindowWatcher.cpp
@@ -292,6 +292,7 @@ nsWindowWatcher::OpenWindow(mozIDOMWindowProxy* aParent, const char* aUrl,
                             /* navigate = */ true, argv,
                             /* aIsPopupSpam = */ false,
                             /* aForceNoOpener = */ false,
+                            /* aForceNoReferrer = */ false,
                             /* aLoadState = */ nullptr, aResult);
 }
 
@@ -347,6 +348,7 @@ nsWindowWatcher::OpenWindow2(mozIDOMWindowProxy* aParent, const char* aUrl,
                              bool aCalledFromScript, bool aDialog,
                              bool aNavigate, nsISupports* aArguments,
                              bool aIsPopupSpam, bool aForceNoOpener,
+                             bool aForceNoReferrer,
                              nsDocShellLoadState* aLoadState,
                              mozIDOMWindowProxy** aResult) {
   nsCOMPtr<nsIArray> argv = ConvertArgsToArray(aArguments);
@@ -366,7 +368,8 @@ nsWindowWatcher::OpenWindow2(mozIDOMWindowProxy* aParent, const char* aUrl,
 
   return OpenWindowInternal(aParent, aUrl, aName, aFeatures, aCalledFromScript,
                             dialog, aNavigate, argv, aIsPopupSpam,
-                            aForceNoOpener, aLoadState, aResult);
+                            aForceNoOpener, aForceNoReferrer, aLoadState,
+                            aResult);
 }
 
 // This static function checks if the aDocShell uses an UserContextId equal to
@@ -575,7 +578,10 @@ nsresult nsWindowWatcher::OpenWindowInternal(
     mozIDOMWindowProxy* aParent, const char* aUrl, const char* aName,
     const char* aFeatures, bool aCalledFromJS, bool aDialog, bool aNavigate,
     nsIArray* aArgv, bool aIsPopupSpam, bool aForceNoOpener,
-    nsDocShellLoadState* aLoadState, mozIDOMWindowProxy** aResult) {
+    bool aForceNoReferrer, nsDocShellLoadState* aLoadState,
+    mozIDOMWindowProxy** aResult) {
+  MOZ_ASSERT_IF(aForceNoReferrer, aForceNoOpener);
+
   nsresult rv = NS_OK;
   bool isNewToplevelWindow = false;
   bool windowIsNew = false;
@@ -758,7 +764,8 @@ nsresult nsWindowWatcher::OpenWindowInternal(
         rv = provider->ProvideWindow(
             aParent, chromeFlags, aCalledFromJS, sizeSpec.PositionSpecified(),
             sizeSpec.SizeSpecified(), uriToLoad, name, features, aForceNoOpener,
-            aLoadState, &windowIsNew, getter_AddRefs(newWindow));
+            aForceNoReferrer, aLoadState, &windowIsNew,
+            getter_AddRefs(newWindow));
 
         if (NS_SUCCEEDED(rv)) {
           GetWindowTreeItem(newWindow, getter_AddRefs(newDocShellItem));
@@ -1076,20 +1083,22 @@ nsresult nsWindowWatcher::OpenWindowInternal(
                "nsWindowWatcher: triggeringPrincipal required");
 #endif
 
-    /* use the URL from the *extant* document, if any. The usual accessor
-       GetDocument will synchronously create an about:blank document if
-       it has no better answer, and we only care about a real document.
-       Also using GetDocument to force document creation seems to
-       screw up focus in the hidden window; see bug 36016.
-    */
-    RefPtr<Document> doc = GetEntryDocument();
-    if (!doc && parentWindow) {
-      doc = parentWindow->GetExtantDoc();
-    }
-    if (doc) {
-      nsCOMPtr<nsIReferrerInfo> referrerInfo =
-          new ReferrerInfo(doc->GetDocumentURI(), doc->GetReferrerPolicy());
-      loadState->SetReferrerInfo(referrerInfo);
+    if (!aForceNoReferrer) {
+      /* use the URL from the *extant* document, if any. The usual accessor
+         GetDocument will synchronously create an about:blank document if
+         it has no better answer, and we only care about a real document.
+         Also using GetDocument to force document creation seems to
+         screw up focus in the hidden window; see bug 36016.
+      */
+      RefPtr<Document> doc = GetEntryDocument();
+      if (!doc && parentWindow) {
+        doc = parentWindow->GetExtantDoc();
+      }
+      if (doc) {
+        nsCOMPtr<nsIReferrerInfo> referrerInfo =
+            new ReferrerInfo(doc->GetDocumentURI(), doc->GetReferrerPolicy());
+        loadState->SetReferrerInfo(referrerInfo);
+      }
     }
   }
 
diff --git a/toolkit/components/windowwatcher/nsWindowWatcher.h b/toolkit/components/windowwatcher/nsWindowWatcher.h
index a308c93b1f88..c48c8f3aeeb4 100644
--- a/toolkit/components/windowwatcher/nsWindowWatcher.h
+++ b/toolkit/components/windowwatcher/nsWindowWatcher.h
@@ -84,7 +84,7 @@ class nsWindowWatcher : public nsIWindowWatcher,
                               const char* aName, const char* aFeatures,
                               bool aCalledFromJS, bool aDialog, bool aNavigate,
                               nsIArray* aArgv, bool aIsPopupSpam,
-                              bool aForceNoOpener,
+                              bool aForceNoOpener, bool aForceNoReferrer,
                               nsDocShellLoadState* aLoadState,
                               mozIDOMWindowProxy** aResult);
 
diff --git a/xpfe/appshell/nsContentTreeOwner.cpp b/xpfe/appshell/nsContentTreeOwner.cpp
index 1d033d51f15f..dedad3b00dfc 100644
--- a/xpfe/appshell/nsContentTreeOwner.cpp
+++ b/xpfe/appshell/nsContentTreeOwner.cpp
@@ -703,7 +703,7 @@ nsContentTreeOwner::ProvideWindow(
     mozIDOMWindowProxy* aParent, uint32_t aChromeFlags, bool aCalledFromJS,
     bool aPositionSpecified, bool aSizeSpecified, nsIURI* aURI,
     const nsAString& aName, const nsACString& aFeatures, bool aForceNoOpener,
-    nsDocShellLoadState* aLoadState, bool* aWindowIsNew,
+    bool aForceNoReferrer, nsDocShellLoadState* aLoadState, bool* aWindowIsNew,
     mozIDOMWindowProxy** aReturn) {
   NS_ENSURE_ARG_POINTER(aParent);
 
@@ -797,6 +797,9 @@ nsContentTreeOwner::ProvideWindow(
     if (aForceNoOpener) {
       flags |= nsIBrowserDOMWindow::OPEN_NO_OPENER;
     }
+    if (aForceNoReferrer) {
+      flags |= nsIBrowserDOMWindow::OPEN_NO_REFERRER;
+    }
 
     // Get a new rendering area from the browserDOMWin.
     // Since we are not loading any URI, we follow the principle of least

Note the borked modeline and changes in that file.

git cinnabar git2hg says that this is https://hg.mozilla.org/mozilla-central/rev/a72c9df6c09aa5cd83cd94a06c05d46334ecfbe2. Which obviously doesn't have those changes.

I'm not sure how to go about debugging this. Doing a git cinnabar fsck for now.

$ git cinnabar --version                                                                                                                                                                     
0.5.1a
module-hash: da246abf7053688705400460e04fe6355f26f6a2
helper-hash: 4423043c1d70cbe87dbdb38ec025b901551ce357/46ccb19fe8d88d212cf26f06fa4760d72ba7fef0
@emilio
Copy link
Author

emilio commented Apr 25, 2019

Hmm, looks like that commit only worsened things. There was also pre-existing bad stuff (the modeline had some copyrev: 1ec0be325e6d41111f155363bf6c6ccfb640c610 gibberish.

@emilio
Copy link
Author

emilio commented Apr 25, 2019

That was introduced in d5c2c553e3174102eb530488929412a3ed75a0f4, which is https://hg.mozilla.org/mozilla-central/rev/d428c2d08e38eb7a05a25e0c603c90745e1427cb.

git show d5c2c553e3174102eb530488929412a3ed75a0f4 says:

commit d5c2c553e3174102eb530488929412a3ed75a0f4
Merge: 51f9bbd30696 096e0ae803f4
Author: Brindusan Cristian <[email protected]>
Date:   Thu Apr 25 01:43:17 2019 +0300

    Merge mozilla-central to autoland. a=merge CLOSED TREE

diff --cc dom/ipc/BrowserParent.cpp
index cd118c7570f6,066d4d4319f3..33fcbdb435a5
--- a/dom/ipc/BrowserParent.cpp
+++ b/dom/ipc/BrowserParent.cpp
@@@ -1,4 -1,4 +1,4 @@@
--/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
++/* -*- Mode: C++; tab-width: 8copyrev: 1ec0be325e6d41111f155363bf6c6ccfb640c610
  /* vim: set ts=8 sts=2 et sw=2 tw=80: */
  /* 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

@emilio
Copy link
Author

emilio commented Apr 25, 2019

git cinnabar fsck doesn't say anything interesting, exits with 0.

@emilio
Copy link
Author

emilio commented Apr 25, 2019

$ git cinnabar hg2git 1ec0be325e6d41111f155363bf6c6ccfb640c610
cd118c7570f611bcb96f220f96ba89a28631fdf1

And git show cd118c7570f611bcb96f220f96ba89a28631fdf1 looks the (correct) blob for that file, IIUC. But at this point I don't know what I'm doing.

@emilio
Copy link
Author

emilio commented Apr 25, 2019

@emilio
Copy link
Author

emilio commented Apr 25, 2019

I'm checking out a separate repo to work today, this one will remain as-is for now so I can wait for you to help debug this.

@glandium
Copy link
Owner

glandium commented May 7, 2019

Duplicate of #207

@glandium glandium marked this as a duplicate of #207 May 7, 2019
@glandium
Copy link
Owner

glandium commented May 7, 2019

Thank you for the copy of your repository. Along with Kate's it's helpful to test improvements to git cinnabar fsck.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants