Bug 1307736 - Store triggeringPrincipal with all history entries. r=mdeboer, a=ritu
authorChristoph Kerschbaumer <ckerschb@christophkerschbaumer.com>
Fri, 27 Jan 2017 11:19:27 +0100
changeset 378114 664f2764b2be48ca5cfc115828d7006468f1d687
parent 378113 f27e061cee9d2e6fc8f11bb2df254f365caca1ef
child 378115 721ea96b25ca00a6c61683ded3d1779da5d46487
push id1419
push userjlund@mozilla.com
push dateMon, 10 Apr 2017 20:44:07 +0000
treeherdermozilla-release@5e6801b73ef6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmdeboer, ritu
bugs1307736
milestone53.0a2
Bug 1307736 - Store triggeringPrincipal with all history entries. r=mdeboer, a=ritu
browser/components/sessionstore/SessionHistory.jsm
browser/components/sessionstore/SessionMigration.jsm
browser/components/sessionstore/SessionStore.jsm
toolkit/modules/sessionstore/Utils.jsm
--- a/browser/components/sessionstore/SessionHistory.jsm
+++ b/browser/components/sessionstore/SessionHistory.jsm
@@ -101,17 +101,20 @@ var SessionHistoryInternal = {
       let body = webNavigation.document.body;
       // We landed here because the history is inaccessible or there are no
       // history entries. In that case we should at least record the docShell's
       // current URL as a single history entry. If the URL is not about:blank
       // or it's a blank tab that was modified (like a custom newtab page),
       // record it. For about:blank we explicitly want an empty array without
       // an 'index' property to denote that there are no history entries.
       if (uri != "about:blank" || (body && body.hasChildNodes())) {
-        data.entries.push({ url: uri });
+        data.entries.push({
+          url: uri,
+          triggeringPrincipal_base64: Utils.SERIALIZED_SYSTEMPRINCIPAL
+        });
         data.index = 1;
       }
     }
 
     // Check if we should discard some of the entries which didn't change
     if (aFromIdx > -1) {
       data.entries.splice(0, aFromIdx + 1);
     }
--- a/browser/components/sessionstore/SessionMigration.jsm
+++ b/browser/components/sessionstore/SessionMigration.jsm
@@ -6,33 +6,36 @@
 
 this.EXPORTED_SYMBOLS = ["SessionMigration"];
 
 const Cu = Components.utils;
 Cu.import("resource://gre/modules/XPCOMUtils.jsm", this);
 Cu.import("resource://gre/modules/Task.jsm", this);
 Cu.import("resource://gre/modules/osfile.jsm", this);
 
+XPCOMUtils.defineLazyModuleGetter(this, "Utils",
+  "resource://gre/modules/sessionstore/Utils.jsm");
+
 // An encoder to UTF-8.
 XPCOMUtils.defineLazyGetter(this, "gEncoder", function () {
   return new TextEncoder();
 });
 
 // A decoder.
 XPCOMUtils.defineLazyGetter(this, "gDecoder", function () {
   return new TextDecoder();
 });
 
 var SessionMigrationInternal = {
   /**
    * Convert the original session restore state into a minimal state. It will
    * only contain:
    * - open windows
    *   - with tabs
-   *     - with history entries with only title, url
+   *     - with history entries with only title, url, triggeringPrincipal
    *     - with pinned state
    *     - with tab group info (hidden + group id)
    *     - with selected tab info
    *   - with selected window info
    *
    * The complete state is then wrapped into the "about:welcomeback" page as
    * form field info to be restored when restoring the state.
    */
@@ -40,32 +43,35 @@ var SessionMigrationInternal = {
     let state = {
       selectedWindow: aStateObj.selectedWindow,
       _closedWindows: []
     };
     state.windows = aStateObj.windows.map(function(oldWin) {
       var win = {extData: {}};
       win.tabs = oldWin.tabs.map(function(oldTab) {
         var tab = {};
-        // Keep only titles and urls for history entries
+        // Keep only titles, urls and triggeringPrincipals for history entries
         tab.entries = oldTab.entries.map(function(entry) {
-          return {url: entry.url, title: entry.title};
+          return { url: entry.url,
+                   triggeringPrincipal_base64: entry.triggeringPrincipal_base64,
+                   title: entry.title };
         });
         tab.index = oldTab.index;
         tab.hidden = oldTab.hidden;
         tab.pinned = oldTab.pinned;
         return tab;
       });
       win.selected = oldWin.selected;
       win._closedTabs = [];
       return win;
     });
     let url = "about:welcomeback";
     let formdata = {id: {sessionData: state}, url};
-    return {windows: [{tabs: [{entries: [{url}], formdata}]}]};
+    let entry = { url, triggeringPrincipal_base64: Utils.SERIALIZED_SYSTEMPRINCIPAL };
+    return { windows: [{ tabs: [{ entries: [ entry ], formdata}]}]};
   },
   /**
    * Asynchronously read session restore state (JSON) from a path
    */
   readState: function(aPath) {
     return Task.spawn(function*() {
       let bytes = yield OS.File.read(aPath);
       let text = gDecoder.decode(bytes);
--- a/browser/components/sessionstore/SessionStore.jsm
+++ b/browser/components/sessionstore/SessionStore.jsm
@@ -623,22 +623,24 @@ var SessionStoreInternal = {
           if (ss.previousSessionCrashed) {
             this._recentCrashes = (state.session &&
                                    state.session.recentCrashes || 0) + 1;
 
             if (this._needsRestorePage(state, this._recentCrashes)) {
               // replace the crashed session with a restore-page-only session
               let url = "about:sessionrestore";
               let formdata = {id: {sessionData: state}, url};
-              state = { windows: [{ tabs: [{ entries: [{url}], formdata }] }] };
+              let entry = {url, triggeringPrincipal_base64: Utils.SERIALIZED_SYSTEMPRINCIPAL };
+              state = { windows: [{ tabs: [{ entries: [entry], formdata }] }] };
             } else if (this._hasSingleTabWithURL(state.windows,
                                                  "about:welcomeback")) {
               // On a single about:welcomeback URL that crashed, replace about:welcomeback
               // with about:sessionrestore, to make clear to the user that we crashed.
               state.windows[0].tabs[0].entries[0].url = "about:sessionrestore";
+              state.windows[0].tabs[0].entries[0].triggeringPrincipal_base64 = Utils.SERIALIZED_SYSTEMPRINCIPAL;
             }
           }
 
           // Update the session start time using the restored session state.
           this._updateSessionStartTime(state);
 
           // make sure that at least the first window doesn't have anything hidden
           delete state.windows[0].hidden;
--- a/toolkit/modules/sessionstore/Utils.jsm
+++ b/toolkit/modules/sessionstore/Utils.jsm
@@ -13,18 +13,23 @@ const Ci = Components.interfaces;
 Cu.import("resource://gre/modules/Services.jsm", this);
 Cu.import("resource://gre/modules/XPCOMUtils.jsm", this);
 
 XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
                                   "resource://gre/modules/NetUtil.jsm");
 XPCOMUtils.defineLazyServiceGetter(this, "serializationHelper",
                                    "@mozilla.org/network/serialization-helper;1",
                                    "nsISerializationHelper");
+XPCOMUtils.defineLazyGetter(this, "SERIALIZED_SYSTEMPRINCIPAL", function() {
+  return Utils.serializePrincipal(Services.scriptSecurityManager.getSystemPrincipal());
+});
 
 this.Utils = Object.freeze({
+  get SERIALIZED_SYSTEMPRINCIPAL() { return SERIALIZED_SYSTEMPRINCIPAL; },
+
   makeURI(url) {
     return Services.io.newURI(url);
   },
 
   makeInputStream(data) {
     if (typeof data == "string") {
       let stream = Cc["@mozilla.org/io/string-input-stream;1"].
                    createInstance(Ci.nsISupportsCString);