Bug 1368068 Fix marionettes excution of javascript when previous sandbox is dead draft
authorMarkus Hartung <markus.hartung@avira.com>
Mon, 03 Jul 2017 09:38:21 +0200
changeset 603231 ef6c09ff4564d34c31c987a1db956af84215be50
parent 603204 6f8f10f48ace5692256efd91f011bd23054ee2ec
child 635846 8c787878dc2c9d02b98ef2ca72f6ae4f3186d8f9
push id66698
push userbmo:markus.hartung@avira.com
push dateMon, 03 Jul 2017 07:51:50 +0000
bugs1368068
milestone56.0a1
Bug 1368068 Fix marionettes excution of javascript when previous sandbox is dead MozReview-Commit-ID: 2xdSnKV4YHI
testing/marionette/evaluate.js
--- a/testing/marionette/evaluate.js
+++ b/testing/marionette/evaluate.js
@@ -294,16 +294,41 @@ evaluate.toJSON = function(obj, seenEls)
       } else {
         throw e;
       }
     }
   }
   return rv;
 };
 
+/**
+ * Cu.isDeadWrapper does not return true for a dead sandbox that was
+ * assosciated with and extension popup. This provides a way to still
+ * test for a dead object.
+ *
+ * @param {?} obj
+ *     A potentially dead object.
+ * @param {string} prop
+ *     Name of a property on the object.
+ *
+ * @returns {boolean}
+ *     True if |obj| is dead, false otherwise.
+ */
+evaluate.isDead = function(obj, prop) {
+  try {
+    obj[prop];
+  } catch (e) {
+    if (e.message.includes("dead object")) {
+      return true;
+    }
+    throw e;
+  }
+  return false;
+};
+
 this.sandbox = {};
 
 /**
  * Provides a safe way to take an object defined in a privileged scope and
  * create a structured clone of it in a less-privileged scope.  It returns
  * a reference to the clone.
  *
  * Unlike for |Components.utils.cloneInto|, |obj| may contain functions
@@ -429,17 +454,17 @@ this.Sandboxes = class {
    *     Remove old sandbox by name first, if it exists.
    *
    * @return {Sandbox}
    *     A used or fresh sandbox.
    */
   get(name = "default", fresh = false) {
     let sb = this.boxes_.get(name);
     if (sb) {
-      if (fresh || sb.window != this.window_) {
+      if (fresh || evaluate.isDead(sb, "window") || sb.window != this.window_) {
         this.boxes_.delete(name);
         return this.get(name, false);
       }
     } else {
       if (name == "system") {
         sb = sandbox.createSystemPrincipal(this.window_);
       } else {
         sb = sandbox.create(this.window_);