Bug 1287007 - Set parent cloneScope to child cloneScope r=billm
authorRob Wu <rob@robwu.nl>
Sun, 11 Sep 2016 03:10:21 -0700
changeset 428719 09fa6078095c96453fb793ee97755cc3c66a986c
parent 428718 54c25251246826c4bca1af8208ddbb0dcb4da0b2
child 428720 4c43afedf60f8852f0a1729123af998da103f50b
push id33405
push userbcampen@mozilla.com
push dateMon, 24 Oct 2016 15:32:53 +0000
reviewersbillm
bugs1287007
milestone52.0a1
Bug 1287007 - Set parent cloneScope to child cloneScope r=billm This is only to help with migration. This change allows all APIs to behave identical regardless of whether the API is proxied. Change cloneScope to be a getter because cloneScope is `this.contentWindow`, which may be nulled when the context navigates away (but stays in the bfcache). Any API that is not proxied must have an identical clone scope to make sure that properties such as toJSON (in the native messaging stringifier) and ArrayBuffer (in webRequest as requestBody) are visible to the caller. MozReview-Commit-ID: 9aT3SUBieHK
toolkit/components/extensions/Extension.jsm
toolkit/components/extensions/ExtensionChild.jsm
--- a/toolkit/components/extensions/Extension.jsm
+++ b/toolkit/components/extensions/Extension.jsm
@@ -322,21 +322,16 @@ class ProxyContext extends BaseContext {
 class ExtensionChildProxyContext extends ProxyContext {
   constructor(envType, extension, params, xulBrowser) {
     super(envType, extension, params, xulBrowser, extension.principal);
 
     this.viewType = params.viewType;
     // WARNING: The xulBrowser may change when docShells are swapped, e.g. when
     // the tab moves to a different window.
     this.xulBrowser = xulBrowser;
-
-    // TODO(robwu): Remove this once all APIs can run in a separate process.
-    if (params.cloneScopeInProcess) {
-      this.sandbox = params.cloneScopeInProcess;
-    }
   }
 
   // The window that contains this context. This may change due to moving tabs.
   get xulWindow() {
     return this.xulBrowser.ownerGlobal;
   }
 
   get windowId() {
--- a/toolkit/components/extensions/ExtensionChild.jsm
+++ b/toolkit/components/extensions/ExtensionChild.jsm
@@ -78,26 +78,36 @@ var apiManager = new class extends Schem
 class WannabeChildAPIManager extends ChildAPIManager {
   createProxyContextInConstructor(data) {
     // Create a structured clone to simulate IPC.
     data = Object.assign({}, data);
     let {principal} = data;  // Not structurally cloneable.
     delete data.principal;
     data = Cu.cloneInto(data, {});
     data.principal = principal;
-    data.cloneScopeInProcess = this.context.cloneScope;
     let name = "API:CreateProxyContext";
     // The <browser> that receives messages from `this.messageManager`.
     let target = this.context.contentWindow
       .QueryInterface(Ci.nsIInterfaceRequestor)
       .getInterface(Ci.nsIDocShell)
       .chromeEventHandler;
     ParentAPIManager.receiveMessage({name, data, target});
 
     let proxyContext = ParentAPIManager.proxyContexts.get(this.id);
+
+    // Use an identical cloneScope in the parent as the child to have identical
+    // behavior for proxied vs direct calls. If all APIs are proxied, then the
+    // parent cloneScope does not really matter (because when the message
+    // arrives locally, the object is cloned into the local clone scope).
+    // If all calls are direct, then the parent cloneScope does matter, because
+    // the objects are not cloned again.
+    Object.defineProperty(proxyContext, "cloneScope", {
+      get: () => this.cloneScope,
+    });
+
     // Many APIs rely on this, so temporarily add it to keep the commit small.
     proxyContext.setContentWindow(this.context.contentWindow);
 
     // Synchronously unload the ProxyContext because we synchronously create it.
     this.context.callOnClose({close: proxyContext.unload.bind(proxyContext)});
   }
 
   getFallbackImplementation(namespace, name) {