Skip to content

Exception when used in Firefox webextension content script #94

@frankier

Description

@frankier

Using this in a Firefox webextension content script will cause an error on the 4th line of makeExporter "Not allowed to define cross-origin object as property on [Object] or [Array] XrayWrapper". The exception is not displayed by default. You can only see it if you "pause on exceptions" in the debugger.

The problem is to do with trying to install an object on window. I think it's to do with the particular pattern here. Simple patching of window should work as desired with Firefox's X-Ray vision (visible to the content script, but not with the web page). Possibly it's the use of defineProperty which causes problems?

Here's some background information:
https://github.com/ricardoquesada/Spidermonkey/blob/master/js/xpconnect/wrappers/XrayWrapper.cpp
https://developer.mozilla.org/en-US/docs/Mozilla/Tech/Xray_vision
https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Sharing_objects_with_page_scripts
https://stackoverflow.com/questions/41704263/error-not-allowed-to-define-cross-origin-object-as-property-on-object-or-arr

The specific issue here seems to relate to whether Reflect is modified on the actual window object, or whether a Sandbox object is used. It's not very well documented, but someone has tried to discover the different behaviours here:
https://stackoverflow.com/questions/44671610/sandboxed-this-in-firefox-webextension-content-script

I have created a pull request with a workaround at #93 . This fixes it, but I'm not sure how good a solution it is.

Since it's quite a niche issue, I also tried seeing if it was possible to work around it in another way. I tried to use a shim in webpack like so:

      {
        test: require.resolve("reflect-metadata"),
        use: "imports-loader?global=>require('global-shim').global"
      }

With global-shim.js being

var global = (function(win) {
  win.__make_sandbox = true;
  return win;
})(window);
export { global };

Or

var global = (function() {
  return this !== window && this.wrappedJSObject === window.wrappedJSObject
    ? this
    : window;
}).call(window);

Neither works. Any input on this slightly mysterious issue is very welcome.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions