Bug 1294866 - Part 1: Move principal serialization to a utils file. r=mikedeboer
authorSteven Englehardt <senglehardt@mozilla.com>
Tue, 13 Sep 2016 21:18:36 +0800
changeset 313850 91be005ab8e60f5f1ade339a8543d4c580cbd494
parent 313849 876a4319c262bff844529614b5343e634d0e3947
child 313851 dafa284120321bef77f46a0a61c1619b72b3de7d
push id32264
push usercbook@mozilla.com
push dateWed, 14 Sep 2016 10:18:20 +0000
treeherderautoland@b9c4a0402a0a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmikedeboer
bugs1294866
milestone51.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 1294866 - Part 1: Move principal serialization to a utils file. r=mikedeboer
browser/components/sessionstore/SessionHistory.jsm
browser/components/sessionstore/Utils.jsm
--- a/browser/components/sessionstore/SessionHistory.jsm
+++ b/browser/components/sessionstore/SessionHistory.jsm
@@ -167,17 +167,17 @@ var SessionHistoryInternal = {
       let x = {}, y = {};
       shEntry.getScrollPosition(x, y);
       if (x.value != 0 || y.value != 0)
         entry.scroll = x.value + "," + y.value;
     }
 
     // Collect triggeringPrincipal data for the current history entry.
     try {
-      let triggeringPrincipal = this.serializeTriggeringPrincipal(shEntry);
+      let triggeringPrincipal = Utils.serializePrincipal(shEntry.triggeringPrincipal);
       if (triggeringPrincipal) {
         entry.triggeringPrincipal_b64 = triggeringPrincipal;
       }
     } catch (ex) {
       // Not catching anything specific here, just possible errors
       // from writeCompoundObject() and the like.
       debug("Failed serializing triggeringPrincipal data: " + ex);
     }
@@ -214,49 +214,16 @@ var SessionHistoryInternal = {
         entry.children = children;
       }
     }
 
     return entry;
   },
 
   /**
-   * Serialize triggeringPrincipal data contained in the given session history entry.
-   *
-   * @param shEntry
-   *        The session history entry.
-   * @return The base64 encoded triggeringPrincipal data.
-   */
-  serializeTriggeringPrincipal: function (shEntry) {
-    if (!shEntry.triggeringPrincipal) {
-      return null;
-    }
-
-    let binaryStream = Cc["@mozilla.org/binaryoutputstream;1"].
-                       createInstance(Ci.nsIObjectOutputStream);
-    let pipe = Cc["@mozilla.org/pipe;1"].createInstance(Ci.nsIPipe);
-    pipe.init(false, false, 0, 0xffffffff, null);
-    binaryStream.setOutputStream(pipe.outputStream);
-    binaryStream.writeCompoundObject(shEntry.triggeringPrincipal, Ci.nsIPrincipal, true);
-    binaryStream.close();
-
-    // Now we want to read the data from the pipe's input end and encode it.
-    let scriptableStream = Cc["@mozilla.org/binaryinputstream;1"].
-                           createInstance(Ci.nsIBinaryInputStream);
-    scriptableStream.setInputStream(pipe.inputStream);
-    let triggeringPrincipalBytes =
-      scriptableStream.readByteArray(scriptableStream.available());
-
-    // We can stop doing base64 encoding once our serialization into JSON
-    // is guaranteed to handle all chars in strings, including embedded
-    // nulls.
-    return btoa(String.fromCharCode.apply(null, triggeringPrincipalBytes));
-  },
-
-  /**
    * Restores session history data for a given docShell.
    *
    * @param docShell
    *        The docShell that owns the session history.
    * @param tabData
    *        The tabdata including all history entries.
    */
   restore: function (docShell, tabData) {
@@ -383,26 +350,17 @@ var SessionHistoryInternal = {
     // Bug 1286472. To remain backward compatible we still have to support that
     // field for a few cycles before we can remove it within Bug 1289785.
     if (entry.owner_b64) {
       entry.triggeringPricipal_b64 = entry.owner_b64;
       delete entry.owner_b64;
     }
 
     if (entry.triggeringPrincipal_b64) {
-      var triggeringPrincipalInput = Cc["@mozilla.org/io/string-input-stream;1"]
-                                       .createInstance(Ci.nsIStringInputStream);
-      var binaryData = atob(entry.triggeringPrincipal_b64);
-      triggeringPrincipalInput.setData(binaryData, binaryData.length);
-      var binaryStream = Cc["@mozilla.org/binaryinputstream;1"].
-                         createInstance(Ci.nsIObjectInputStream);
-      binaryStream.setInputStream(triggeringPrincipalInput);
-      try { // Catch possible deserialization exceptions
-        shEntry.triggeringPrincipal = binaryStream.readObject(true);
-      } catch (ex) { debug(ex); }
+      shEntry.triggeringPrincipal = Utils.deserializePrincipal(entry.triggeringPrincipal_b64);
     }
 
     if (entry.children && shEntry instanceof Ci.nsISHContainer) {
       for (var i = 0; i < entry.children.length; i++) {
         //XXXzpao Wallpaper patch for bug 514751
         if (!entry.children[i].url)
           continue;
 
--- a/browser/components/sessionstore/Utils.jsm
+++ b/browser/components/sessionstore/Utils.jsm
@@ -6,16 +6,21 @@
 
 this.EXPORTED_SYMBOLS = ["Utils"];
 
 const Cu = Components.utils;
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 
 Cu.import("resource://gre/modules/Services.jsm", this);
+Cu.import("resource://gre/modules/XPCOMUtils.jsm", this);
+
+XPCOMUtils.defineLazyServiceGetter(this, "serializationHelper",
+                                   "@mozilla.org/network/serialization-helper;1",
+                                   "nsISerializationHelper");
 
 this.Utils = Object.freeze({
   makeURI: function (url) {
     return Services.io.newURI(url, null, null);
   },
 
   makeInputStream: function (aString) {
     let stream = Cc["@mozilla.org/io/string-input-stream;1"].
@@ -55,10 +60,40 @@ this.Utils = Object.freeze({
   shallowCopy: function (obj) {
     let retval = {};
 
     for (let key of Object.keys(obj)) {
       retval[key] = obj[key];
     }
 
     return retval;
+  },
+
+  /**
+   * Serialize principal data.
+   *
+   * @param {nsIPrincipal} principal The principal to serialize.
+   * @return {String} The base64 encoded principal data.
+   */
+  serializePrincipal(principal) {
+    if (!principal)
+      return null;
+
+    return serializationHelper.serializeToString(principal);
+  },
+
+  /**
+   * Deserialize a base64 encoded principal (serialized with
+   * Utils::serializePrincipal).
+   *
+   * @param {String} principal_b64 A base64 encoded serialized principal.
+   * @return {nsIPrincipal} A deserialized principal.
+   */
+  deserializePrincipal(principal_b64) {
+    if (!principal_b64)
+      return null;
+
+    let principal = serializationHelper.deserializeObject(principal_b64);
+    principal.QueryInterface(Ci.nsIPrincipal);
+
+    return principal;
   }
 });