Bug 790201. Nuke social worker sandbox on shutdown. r=mhammond
☠☠ backed out by 9b9678df7672 ☠ ☠
authorFelipe Gomes <felipc@gmail.com>
Fri, 05 Oct 2012 17:22:09 -0700
changeset 109467 e9237d1ae5ff3642cd6a52a045671b0e3d7f843b
parent 109466 0ecee5121681d91f159f4a015233c723c0b3f08e
child 109468 876520b68263587c9d01143a3a4997026dd2268c
push id16041
push userfelipc@gmail.com
push dateSat, 06 Oct 2012 00:22:58 +0000
treeherdermozilla-inbound@e9237d1ae5ff [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmhammond
bugs790201
milestone18.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 790201. Nuke social worker sandbox on shutdown. r=mhammond
toolkit/components/social/FrameWorker.jsm
--- a/toolkit/components/social/FrameWorker.jsm
+++ b/toolkit/components/social/FrameWorker.jsm
@@ -72,17 +72,17 @@ function FrameWorker(url, name) {
 
   this.frame = makeHiddenFrame();
 
   var self = this;
   Services.obs.addObserver(function injectController(doc, topic, data) {
     if (!doc.defaultView || doc.defaultView != self.frame.contentWindow) {
       return;
     }
-    Services.obs.removeObserver(injectController, "document-element-inserted", false);
+    Services.obs.removeObserver(injectController, "document-element-inserted");
     try {
       self.createSandbox();
     } catch (e) {
       Cu.reportError("FrameWorker: failed to create sandbox for " + url + ". " + e);
     }
   }, "document-element-inserted", false);
 
   this.frame.setAttribute("src", url);
@@ -98,18 +98,21 @@ FrameWorker.prototype = {
     // safe to import this way
     let workerAPI = ['MozWebSocket', 'WebSocket', 'localStorage',
                      'atob', 'btoa', 'clearInterval', 'clearTimeout', 'dump',
                      'setInterval', 'setTimeout', 'XMLHttpRequest',
                      'MozBlobBuilder', 'FileReader', 'Blob',
                      'location'];
     workerAPI.forEach(function(fn) {
       try {
-        // XXX Need to unwrap for this to work - find out why!
-        sandbox[fn] = XPCNativeWrapper.unwrap(workerWindow)[fn];
+        sandbox[fn] = workerWindow[fn];
+        // Bug 798660 - XHR has issues in a sandbox and need
+        // to be unwrapped to work
+        if (fn == "XMLHttpRequest")
+          sandbox[fn] = XPCNativeWrapper.unwrap(workerWindow)[fn];
       }
       catch(e) {
         Cu.reportError("FrameWorker: failed to import API "+fn+"\n"+e+"\n");
       }
     });
     // the "navigator" object in a worker is a subset of the full navigator;
     // specifically, just the interfaces 'NavigatorID' and 'NavigatorOnLine'
     let navigator = {
@@ -148,18 +151,24 @@ FrameWorker.prototype = {
 
     sandbox._postMessage = function fw_postMessage(d, o) {
       workerWindow.postMessage(d, o)
     };
     sandbox._addEventListener = function fw_addEventListener(t, l, c) {
       workerWindow.addEventListener(t, l, c)
     };
 
+    // This is necessary to keep the sandbox alive
     this.sandbox = sandbox;
 
+    Services.obs.addObserver(function cleanupSandbox () {
+      Services.obs.removeObserver(cleanupSandbox, "xpcom-shutdown");
+      Cu.nukeSandbox(sandbox);
+    }, "xpcom-shutdown", false);
+
     let worker = this;
 
     workerWindow.addEventListener("load", function loadListener() {
       workerWindow.removeEventListener("load", loadListener);
       // the iframe has loaded the js file as text - first inject the magic
       // port-handling code into the sandbox.
       try {
         Services.scriptloader.loadSubScript("resource://gre/modules/MessagePortBase.jsm", sandbox);
@@ -221,16 +230,18 @@ FrameWorker.prototype = {
 
     delete workerCache[this.url];
 
     // let pending events get delivered before actually removing the frame
     Services.tm.mainThread.dispatch(function deleteWorkerFrame() {
       // now nuke the iframe itself and forget everything about this worker.
       this.frame.parentNode.removeChild(this.frame);
     }.bind(this), Ci.nsIThread.DISPATCH_NORMAL);
+
+    Cu.nukeSandbox(this.sandbox);
   }
 };
 
 function makeHiddenFrame() {
   let hiddenDoc = Services.appShell.hiddenDOMWindow.document;
   let iframe = hiddenDoc.createElementNS("http://www.w3.org/1999/xhtml", "iframe");
   iframe.setAttribute("mozframetype", "content");
   // allow-same-origin is necessary for localStorage to work in the sandbox.