Closed Bug 1475950 Opened 6 years ago Closed 6 years ago

Error: Not allowed to define cross-origin object as property on [Object] or [Array] XrayWrapper

Categories

(WebExtensions :: General, defect)

61 Branch
defect
Not set
normal

Tracking

(Not tracked)

RESOLVED DUPLICATE of bug 1208775

People

(Reporter: d.sai535, Unassigned)

Details

Attachments

(2 files)

Attached image firefox-error.PNG
User Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36

Steps to reproduce:

I've developed extension using Angular which works well on Chrome but, doesn't work on Firefox. Since firefox works differently compared to chrome as mentioned here https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Sharing_objects_with_page_scripts. I'm unable to figure out where to make these changes to work.




Actual results:

Now, when I run my extension it throws error "Error: Not allowed to define cross-origin object as property on [Object] or [Array] XrayWrapper"


Expected results:

I should be able to see my extension.
Error stack show's as below In polyfills.bundle.js.

  // hook global Reflect
    (function (__global) {
        console.log('label', window.wrappedJSObject);
        if (typeof __global.Reflect !== "undefined") {
            if (__global.Reflect !== Reflect) {
                for (var p in Reflect) {
                    __global.Reflect[p] = Reflect[p]; // Error line
                }
            }
        }
        else {
            __global.Reflect = Reflect;
        }
    })(typeof window !== "undefined" ? window :
        typeof WorkerGlobalScope !== "undefined" ? self :
            typeof global !== "undefined" ? global :
                Function("return this;")());
})(Reflect || (Reflect = {}))

manifest.json as follows

{
    "applications": {
      "gecko": {
        "id": "some@email.com"
      }
    },
    "manifest_version": 2,
    "name": "Extension name",
    "version": "2.5.1822",
    "description": "",
    "icons": {
      "16": "assets/icon/icon16.png",
      "32": "assets/icon/icon32.png",
      "48": "assets/icon/icon48.png",
      "128": "assets/icon/icon128.png"
    },
    "permissions": [
      "*://*/*",
      "browsingData",
      "cookies",
      "storage",
      "tabs",
      "webRequest",
      "webRequestBlocking"
    ],
    "content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self';",
    "web_accessible_resources": ["*"],
    "background": {
      "scripts": ["content-script.js"]
    },
    "browser_action": {
      "default_title": "Some Player"
    }
  }

content-script.js as follows

async function register() {
  return await browser.contentScripts.register({
    allFrames: true,
    js: [
      {
        file: 'polyfills.bundle.js'
      },
      {
        file: 'vendor.bundle.js'
      },
      {
        file: 'main.bundle.js'
      },
      {
        file: 'libraries.bundle.js'
      }
    ],
    css: [{
      file: 'styles.bundle.css'
    }],
    "matches": ["*://*/*"],
    "allFrames": true,
    "runAt": "document_start"
  });

}


var registered = register();```
The error message is correct.

In normal web pages, the "window" window namespace is the global scope.
In WebExtension content scripts, "window" refers to the global scope of the page (through security wrappers - see https://developer.mozilla.org/en-US/docs/Mozilla/Tech/Xray_vision) and the global scope can be accessed with "this".

Your example boils down to:

    window.Reflect.apply = Reflect.apply;

The "window.Reflect" at the left side refers to the page's "Reflect" object (via a so-called XRayWrapper),
whereas "Reflect" refers to the "Reflect" in the global scope of the content script.

So to fix your code you need to stop using "window", and use "this" instead:

    this.Reflect.apply = Reflect.apply


This appears to be a known issue in the library that you are using:
https://github.com/rbuckton/reflect-metadata/issues/94

which is fixed by this pull request:
https://github.com/rbuckton/reflect-metadata/pull/93

( This also seems to be cross-posted at https://stackoverflow.com/questions/51358950/extension-works-chrome-on-but-doesnt-work-on-firefox-due-to-object-or-array )
Status: UNCONFIRMED → RESOLVED
Closed: 6 years ago
Component: Untriaged → General
Product: Firefox → WebExtensions
Resolution: --- → DUPLICATE
(In reply to Rob Wu [:robwu] from comment #2)
> The error message is correct.
> 
> In normal web pages, the "window" window namespace is the global scope.
> In WebExtension content scripts, "window" refers to the global scope of the
> page (through security wrappers - see
> https://developer.mozilla.org/en-US/docs/Mozilla/Tech/Xray_vision) and the
> global scope can be accessed with "this".
> 
> Your example boils down to:
> 
>     window.Reflect.apply = Reflect.apply;
> 
> The "window.Reflect" at the left side refers to the page's "Reflect" object
> (via a so-called XRayWrapper),
> whereas "Reflect" refers to the "Reflect" in the global scope of the content
> script.
> 
> So to fix your code you need to stop using "window", and use "this" instead:
> 
>     this.Reflect.apply = Reflect.apply
> 
> 
> This appears to be a known issue in the library that you are using:
> https://github.com/rbuckton/reflect-metadata/issues/94
> 
> which is fixed by this pull request:
> https://github.com/rbuckton/reflect-metadata/pull/93
> 
> ( This also seems to be cross-posted at
> https://stackoverflow.com/questions/51358950/extension-works-chrome-on-but-
> doesnt-work-on-firefox-due-to-object-or-array )

Thanks for you response. I've replaced window with "this" that result in error "TypeError: "fetch" is read-only" and stack as follows 


function zoneify(fn) {
        return function () {
            var resultPromise = fn.apply(this, arguments);
            if (resultPromise instanceof ZoneAwarePromise) {
                return resultPromise;
            }
            var ctor = resultPromise.constructor;
            if (!ctor[symbolThenPatched]) {
                patchThen(ctor);
            }
            return resultPromise;
        };
    }
    if (NativePromise) {
        patchThen(NativePromise);
        var fetch_1 = global['fetch'];
        if (typeof fetch_1 == 'function') {
            global['fetch'] = zoneify(fetch_1); // error line
        }
    }
    // This is not part of public API, but it is useful for tests, so we expose it.
    Promise[Zone.__symbol__('uncaughtPromiseErrors')] = _uncaughtPromiseErrors;
    return ZoneAwarePromise;
(In reply to saiumesh from comment #3)
> Thanks for you response. I've replaced window with "this" that result in
> error "TypeError: "fetch" is read-only" and stack as follows 

I'm not getting any error in Firefox 61 and 63 when I create a content script with the following code:

    this.fetch = null;
(In reply to Rob Wu [:robwu] from comment #4)
> (In reply to saiumesh from comment #3)
> > Thanks for you response. I've replaced window with "this" that result in
> > error "TypeError: "fetch" is read-only" and stack as follows 
> 
> I'm not getting any error in Firefox 61 and 63 when I create a content
> script with the following code:
> 
>     this.fetch = null;

Hello Rob, unfortunately it didn't work.

error stack as follows 

var global = module.exports = typeof window != 'undefined' && window.Math == Math
  ? window : typeof self != 'undefined' && self.Math == Math ? self
  // eslint-disable-next-line no-new-func
  : Function('return this')();

function zoneify(fn) {
        return function () {
            var resultPromise = fn.apply(this, arguments);
            if (resultPromise instanceof ZoneAwarePromise) {
                return resultPromise;
            }
            var ctor = resultPromise.constructor;
            if (!ctor[symbolThenPatched]) {
                patchThen(ctor);
            }
            return resultPromise;
        };
    }
    if (NativePromise) {
        patchThen(NativePromise);
        var fetch_1 = global['fetch'];
        if (typeof fetch_1 == 'function') {
            global['fetch'] = zoneify(fetch_1); // error line
        }
    }
The code you've shared suggests that "fetch" is read-only, and that "this.fetch = null;" would throw.
I have shown that "this.fetch = null" does not throw, thus "fetch" is not read-only.

If you see otherwise, please share a code snippet that has the problem and include the Firefox version that you are using for testing.
Attached file polyfills.bundle.js
(In reply to Rob Wu [:robwu] from comment #6)
> The code you've shared suggests that "fetch" is read-only, and that
> "this.fetch = null;" would throw.
> I have shown that "this.fetch = null" does not throw, thus "fetch" is not
> read-only.
> 
> If you see otherwise, please share a code snippet that has the problem and
> include the Firefox version that you are using for testing.

sure. (In reply to saiumesh from comment #7)
> Created attachment 8992911 [details]
> polyfills.bundle.js

I've attached my polyfills file.
Your library uses "window" in multiple locations instead of "this".

If you aren't able to patch every use of "window", consider wrapping the whole library in a closure where "window" is "this":

(window => {
// Paste library here
})(this);
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: