Bug 1287007 - Set parent cloneScope to child cloneScope draft
authorRob Wu <rob@robwu.nl>
Sun, 11 Sep 2016 03:10:21 -0700
changeset 428440 8797b10128a9f2123c53b9d57000f8e7e80231f7
parent 428439 206a577e675029584758314c892745dd6b368aec
child 428441 b7e7d17397f56582808bded171b0ffedd69e2dc2
push id33305
push userbmo:rob@robwu.nl
push dateSun, 23 Oct 2016 20:56:25 +0000
bugs1287007
milestone52.0a1
Bug 1287007 - Set parent cloneScope to child cloneScope 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) {