Bug 1331686 - Pass correct triggeringPrincipal for tabs openen through ctrl-click and open link in new tab. r=gijs
authorChristoph Kerschbaumer <ckerschb@christophkerschbaumer.com>
Sun, 22 Jan 2017 11:47:36 +0100
changeset 375570 338508c5cc01f6ad368fc7672048c3153755b838
parent 375569 80d47de5e1bf04fd59ba08df1e438ee4640e04d1
child 375571 3444d123020d204cbe94053c32987c4ee495c8f6
push id6996
push userjlorenzo@mozilla.com
push dateMon, 06 Mar 2017 20:48:21 +0000
treeherdermozilla-beta@d89512dab048 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgijs
bugs1331686
milestone53.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 1331686 - Pass correct triggeringPrincipal for tabs openen through ctrl-click and open link in new tab. r=gijs
browser/base/content/browser.js
browser/base/content/content.js
browser/base/content/tabbrowser.xml
browser/base/content/utilityOverlay.js
toolkit/content/widgets/browser.xml
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -106,16 +106,19 @@ if (AppConstants.MOZ_CRASHREPORTER) {
 ].forEach(([name, cc, ci]) => XPCOMUtils.defineLazyServiceGetter(this, name, cc, ci));
 
 if (AppConstants.MOZ_CRASHREPORTER) {
   XPCOMUtils.defineLazyServiceGetter(this, "gCrashReporter",
                                      "@mozilla.org/xre/app-info;1",
                                      "nsICrashReporter");
 }
 
+XPCOMUtils.defineLazyServiceGetter(this, "gSerializationHelper",
+                                   "@mozilla.org/network/serialization-helper;1",
+                                   "nsISerializationHelper");
 
 XPCOMUtils.defineLazyGetter(this, "BrowserToolboxProcess", function() {
   let tmp = {};
   Cu.import("resource://devtools/client/framework/ToolboxProcess.jsm", tmp);
   return tmp.BrowserToolboxProcess;
 });
 
 XPCOMUtils.defineLazyGetter(this, "gBrowserBundle", function() {
@@ -858,16 +861,17 @@ function serializeInputStream(aStream) {
 }
 
 // A shared function used by both remote and non-remote browser XBL bindings to
 // load a URI or redirect it to the correct process.
 function _loadURIWithFlags(browser, uri, params) {
   if (!uri) {
     uri = "about:blank";
   }
+  let triggeringPrincipal = params.triggeringPrincipal || null;
   let flags = params.flags || 0;
   let referrer = params.referrerURI;
   let referrerPolicy = ("referrerPolicy" in params ? params.referrerPolicy :
                         Ci.nsIHttpChannel.REFERRER_POLICY_UNSET);
   let postData = params.postData;
 
   let currentRemoteType = browser.remoteType;
   let requiredRemoteType =
@@ -881,30 +885,33 @@ function _loadURIWithFlags(browser, uri,
   try {
     if (!mustChangeProcess) {
       if (params.userContextId) {
         browser.webNavigation.setOriginAttributesBeforeLoading({ userContextId: params.userContextId });
       }
 
       browser.webNavigation.loadURIWithOptions(uri, flags,
                                                referrer, referrerPolicy,
-                                               postData, null, null);
+                                               postData, null, null, triggeringPrincipal);
     } else {
       // Check if the current browser is allowed to unload.
       let {permitUnload, timedOut} = browser.permitUnload();
       if (!timedOut && !permitUnload) {
         return;
       }
 
       if (postData) {
         postData = serializeInputStream(postData);
       }
 
       let loadParams = {
         uri,
+        triggeringPrincipal: triggeringPrincipal
+          ? gSerializationHelper.serializePrincipal(triggeringPrincipal)
+          : null,
         flags,
         referrer: referrer ? referrer.spec : null,
         referrerPolicy,
         postData
       }
 
       if (params.userContextId) {
         loadParams.userContextId = params.userContextId;
@@ -922,17 +929,17 @@ function _loadURIWithFlags(browser, uri,
       Cu.reportError(e);
       gBrowser.updateBrowserRemotenessByURL(browser, uri);
 
       if (params.userContextId) {
         browser.webNavigation.setOriginAttributesBeforeLoading({ userContextId: params.userContextId });
       }
 
       browser.webNavigation.loadURIWithOptions(uri, flags, referrer, referrerPolicy,
-                                               postData, null, null);
+                                               postData, null, null, triggeringPrincipal);
     } else {
       throw e;
     }
   } finally {
     if (!requiredRemoteType) {
       browser.inLoadURI = false;
     }
   }
@@ -4951,17 +4958,17 @@ var TabsProgressListener = {
 function nsBrowserAccess() { }
 
 nsBrowserAccess.prototype = {
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIBrowserDOMWindow, Ci.nsISupports]),
 
   _openURIInNewTab(aURI, aReferrer, aReferrerPolicy, aIsPrivate,
                              aIsExternal, aForceNotRemote = false,
                              aUserContextId = Ci.nsIScriptSecurityManager.DEFAULT_USER_CONTEXT_ID,
-                             aOpener = null) {
+                             aOpener = null, aTriggeringPrincipal = null) {
     let win, needToFocusWin;
 
     // try the current window.  if we're in a popup, fall back on the most recent browser window
     if (window.toolbar.visible)
       win = window;
     else {
       win = RecentWindow.getMostRecentBrowserWindow({private: aIsPrivate});
       needToFocusWin = true;
@@ -4976,16 +4983,17 @@ nsBrowserAccess.prototype = {
       win.BrowserOpenTab(); // this also focuses the location bar
       win.focus();
       return win.gBrowser.selectedBrowser;
     }
 
     let loadInBackground = gPrefService.getBoolPref("browser.tabs.loadDivertedInBackground");
 
     let tab = win.gBrowser.loadOneTab(aURI ? aURI.spec : "about:blank", {
+                                      triggeringPrincipal: aTriggeringPrincipal,
                                       referrerURI: aReferrer,
                                       referrerPolicy: aReferrerPolicy,
                                       userContextId: aUserContextId,
                                       fromExternal: aIsExternal,
                                       inBackground: loadInBackground,
                                       forceNotRemote: aForceNotRemote,
                                       opener: aOpener,
                                       });
@@ -5024,19 +5032,21 @@ nsBrowserAccess.prototype = {
       if (isExternal &&
           gPrefService.prefHasUserValue("browser.link.open_newwindow.override.external"))
         aWhere = gPrefService.getIntPref("browser.link.open_newwindow.override.external");
       else
         aWhere = gPrefService.getIntPref("browser.link.open_newwindow");
     }
 
     let referrer = aOpener ? makeURI(aOpener.location.href) : null;
+    let triggeringPrincipal = null;
     let referrerPolicy = Ci.nsIHttpChannel.REFERRER_POLICY_UNSET;
     if (aOpener && aOpener.document) {
       referrerPolicy = aOpener.document.referrerPolicy;
+      triggeringPrincipal = aOpener.document.nodePrincipal;
     }
     let isPrivate = aOpener
                   ? PrivateBrowsingUtils.isContentWindowPrivate(aOpener)
                   : PrivateBrowsingUtils.isWindowPrivate(window);
 
     switch (aWhere) {
       case Ci.nsIBrowserDOMWindow.OPEN_NEWWINDOW :
         // FIXME: Bug 408379. So how come this doesn't send the
@@ -5060,27 +5070,28 @@ nsBrowserAccess.prototype = {
         let forceNotRemote = !!aOpener;
         let userContextId = aOpener && aOpener.document
                               ? aOpener.document.nodePrincipal.originAttributes.userContextId
                               : Ci.nsIScriptSecurityManager.DEFAULT_USER_CONTEXT_ID;
         let openerWindow = (aFlags & Ci.nsIBrowserDOMWindow.OPEN_NO_OPENER) ? null : aOpener;
         let browser = this._openURIInNewTab(aURI, referrer, referrerPolicy,
                                             isPrivate, isExternal,
                                             forceNotRemote, userContextId,
-                                            openerWindow);
+                                            openerWindow, triggeringPrincipal);
         if (browser)
           newWindow = browser.contentWindow;
         break;
       default : // OPEN_CURRENTWINDOW or an illegal value
         newWindow = content;
         if (aURI) {
           let loadflags = isExternal ?
                             Ci.nsIWebNavigation.LOAD_FLAGS_FROM_EXTERNAL :
                             Ci.nsIWebNavigation.LOAD_FLAGS_NONE;
           gBrowser.loadURIWithFlags(aURI.spec, {
+                                    triggeringPrincipal,
                                     flags: loadflags,
                                     referrerURI: referrer,
                                     referrerPolicy,
                                     });
         }
         if (!gPrefService.getBoolPref("browser.tabs.loadDivertedInBackground"))
           window.focus();
     }
@@ -5100,17 +5111,18 @@ nsBrowserAccess.prototype = {
                           ? aParams.openerOriginAttributes.userContextId
                           : Ci.nsIScriptSecurityManager.DEFAULT_USER_CONTEXT_ID
 
     let referrer = aParams.referrer ? makeURI(aParams.referrer) : null;
     let browser = this._openURIInNewTab(aURI, referrer,
                                         aParams.referrerPolicy,
                                         aParams.isPrivate,
                                         isExternal, false,
-                                        userContextId);
+                                        userContextId, null,
+                                        aParams.triggeringPrincipal);
     if (browser)
       return browser.QueryInterface(Ci.nsIFrameLoaderOwner);
 
     return null;
   },
 
   isTabContentWindow(aWindow) {
     return gBrowser.browsers.some(browser => browser.contentWindow == aWindow);
--- a/browser/base/content/content.js
+++ b/browser/base/content/content.js
@@ -507,16 +507,17 @@ var ClickEventHandler = {
         referrerPolicy = referrerAttrValue;
       }
     }
 
     let json = { button: event.button, shiftKey: event.shiftKey,
                  ctrlKey: event.ctrlKey, metaKey: event.metaKey,
                  altKey: event.altKey, href: null, title: null,
                  bookmark: false, referrerPolicy,
+                 triggeringPrincipal: principal,
                  originAttributes: principal ? principal.originAttributes : {},
                  isContentWindowPrivate: PrivateBrowsingUtils.isContentWindowPrivate(ownerDoc.defaultView)};
 
     if (href) {
       try {
         BrowserUtils.urlSecurityCheck(href, principal);
       } catch (e) {
         return;
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -1500,32 +1500,34 @@
         <parameter name="aReferrerURI"/>
         <parameter name="aCharset"/>
         <parameter name="aPostData"/>
         <parameter name="aLoadInBackground"/>
         <parameter name="aAllowThirdPartyFixup"/>
         <parameter name="aIsPrerendered"/>
         <body>
           <![CDATA[
+            var aTriggeringPrincipal;
             var aReferrerPolicy;
             var aFromExternal;
             var aRelatedToCurrent;
             var aAllowMixedContent;
             var aSkipAnimation;
             var aForceNotRemote;
             var aPreferredRemoteType;
             var aNoReferrer;
             var aUserContextId;
             var aRelatedBrowser;
             var aOriginPrincipal;
             var aOpener;
             if (arguments.length == 2 &&
                 typeof arguments[1] == "object" &&
                 !(arguments[1] instanceof Ci.nsIURI)) {
               let params = arguments[1];
+              aTriggeringPrincipal  = params.triggeringPrincipal
               aReferrerURI          = params.referrerURI;
               aReferrerPolicy       = params.referrerPolicy;
               aCharset              = params.charset;
               aPostData             = params.postData;
               aLoadInBackground     = params.inBackground;
               aAllowThirdPartyFixup = params.allowThirdPartyFixup;
               aFromExternal         = params.fromExternal;
               aRelatedToCurrent     = params.relatedToCurrent;
@@ -1539,17 +1541,19 @@
               aOriginPrincipal      = params.originPrincipal;
               aOpener               = params.opener;
               aIsPrerendered        = params.isPrerendered;
             }
 
             var bgLoad = (aLoadInBackground != null) ? aLoadInBackground :
                          Services.prefs.getBoolPref("browser.tabs.loadInBackground");
             var owner = bgLoad ? null : this.selectedTab;
+
             var tab = this.addTab(aURI, {
+                                  triggeringPrincipal: aTriggeringPrincipal,
                                   referrerURI: aReferrerURI,
                                   referrerPolicy: aReferrerPolicy,
                                   charset: aCharset,
                                   postData: aPostData,
                                   ownerTab: owner,
                                   allowThirdPartyFixup: aAllowThirdPartyFixup,
                                   fromExternal: aFromExternal,
                                   relatedToCurrent: aRelatedToCurrent,
@@ -2136,16 +2140,17 @@
         <parameter name="aOwner"/>
         <parameter name="aAllowThirdPartyFixup"/>
         <parameter name="aIsPrerendered"/>
         <body>
           <![CDATA[
             "use strict";
 
             const NS_XUL = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
+            var aTriggeringPrincipal;
             var aReferrerPolicy;
             var aFromExternal;
             var aRelatedToCurrent;
             var aSkipAnimation;
             var aAllowMixedContent;
             var aForceNotRemote;
             var aPreferredRemoteType;
             var aNoReferrer;
@@ -2154,16 +2159,17 @@
             var aRelatedBrowser;
             var aOriginPrincipal;
             var aDisallowInheritPrincipal;
             var aOpener;
             if (arguments.length == 2 &&
                 typeof arguments[1] == "object" &&
                 !(arguments[1] instanceof Ci.nsIURI)) {
               let params = arguments[1];
+              aTriggeringPrincipal      = params.triggeringPrincipal;
               aReferrerURI              = params.referrerURI;
               aReferrerPolicy           = params.referrerPolicy;
               aCharset                  = params.charset;
               aPostData                 = params.postData;
               aOwner                    = params.ownerTab;
               aAllowThirdPartyFixup     = params.allowThirdPartyFixup;
               aFromExternal             = params.fromExternal;
               aRelatedToCurrent         = params.relatedToCurrent;
@@ -2301,16 +2307,17 @@
                 flags |= Ci.nsIWebNavigation.LOAD_FLAGS_FROM_EXTERNAL;
               if (aAllowMixedContent)
                 flags |= Ci.nsIWebNavigation.LOAD_FLAGS_ALLOW_MIXED_CONTENT;
               if (aDisallowInheritPrincipal)
                 flags |= Ci.nsIWebNavigation.LOAD_FLAGS_DISALLOW_INHERIT_PRINCIPAL;
               try {
                 b.loadURIWithFlags(aURI, {
                   flags,
+                  triggeringPrincipal: aTriggeringPrincipal,
                   referrerURI: aNoReferrer ? null : aReferrerURI,
                   referrerPolicy: aReferrerPolicy,
                   charset: aCharset,
                   postData: aPostData,
                 });
               } catch (ex) {
                 Cu.reportError(ex);
               }
--- a/browser/base/content/utilityOverlay.js
+++ b/browser/base/content/utilityOverlay.js
@@ -373,16 +373,17 @@ function openLinkIn(url, where, params) 
       flags |= Ci.nsIWebNavigation.LOAD_FLAGS_ERROR_LOAD_CHANGES_RV;
     }
 
     if (aForceAboutBlankViewerInCurrent) {
       targetBrowser.createAboutBlankContentViewer(aPrincipal);
     }
 
     targetBrowser.loadURIWithFlags(url, {
+      triggeringPrincipal: aPrincipal,
       flags,
       referrerURI: aNoReferrer ? null : aReferrerURI,
       referrerPolicy: aReferrerPolicy,
       postData: aPostData,
       userContextId: aUserContextId
     });
     break;
   case "tabshifted":
@@ -397,16 +398,17 @@ function openLinkIn(url, where, params) 
       inBackground: loadInBackground,
       allowThirdPartyFixup: aAllowThirdPartyFixup,
       relatedToCurrent: aRelatedToCurrent,
       skipAnimation: aSkipTabAnimation,
       allowMixedContent: aAllowMixedContent,
       noReferrer: aNoReferrer,
       userContextId: aUserContextId,
       originPrincipal: aPrincipal,
+      triggeringPrincipal: aPrincipal,
     });
     targetBrowser = tabUsedForLoad.linkedBrowser;
     break;
   }
 
   // Focus the content, but only if the browser used for the load is selected.
   if (targetBrowser == w.gBrowser.selectedBrowser) {
     targetBrowser.focus();
--- a/toolkit/content/widgets/browser.xml
+++ b/toolkit/content/widgets/browser.xml
@@ -129,33 +129,37 @@
         <parameter name="aCharset"/>
         <parameter name="aPostData"/>
         <body>
           <![CDATA[
             if (!aURI)
               aURI = "about:blank";
 
             var aReferrerPolicy = Components.interfaces.nsIHttpChannel.REFERRER_POLICY_UNSET;
+            var aTriggeringPrincipal;
 
             // Check for loadURIWithFlags(uri, { ... });
             var params = arguments[1];
             if (params && typeof(params) == "object") {
               aFlags = params.flags;
               aReferrerURI = params.referrerURI;
               if ("referrerPolicy" in params) {
                 aReferrerPolicy = params.referrerPolicy;
               }
+              if ("triggeringPrincipal" in params) {
+                aTriggeringPrincipal = params.triggeringPrincipal;
+              }
               aCharset = params.charset;
               aPostData = params.postData;
             }
 
             this._wrapURIChangeCall(() =>
               this.webNavigation.loadURIWithOptions(
                   aURI, aFlags, aReferrerURI, aReferrerPolicy,
-                  aPostData, null, null));
+                  aPostData, null, null, aTriggeringPrincipal));
           ]]>
         </body>
       </method>
 
       <method name="goHome">
         <body>
           <![CDATA[
             try {