Closed Bug 1408996 Opened 7 years ago Closed 5 years ago

Expando object for Sandbox Window wrapper sometimes gets lost

Categories

(Core :: XPConnect, defect, P3)

57 Branch
defect

Tracking

()

RESOLVED FIXED
mozilla67
Tracking Status
firefox67 --- fixed

People

(Reporter: sandees, Assigned: bzbarsky)

References

Details

Attachments

(1 file)

330.04 KB, application/zip
Details
User Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:57.0) Gecko/20100101 Firefox/57.0
Build ID: 20171013042429

Steps to reproduce:

Open bbc.com or money.cnn.com.
Click on WebExtension Icon.
The onclick listener eventually invokes script injection code inside extesnion's content script.
Both content script and the jQuery file are specifically mentioned in the extension's manifest under the "content scripts" key:attribute pair.

 Content Script uses the below JQuery selector:
      $iframe = $("#__acrobatDialog__");

On debugging, jQuery variable "$" remains unloaded/undefined.

And there is a silent crash at this statement.

The issue is intermittent, it gets automatically fixed in some updates of nightly/FF and starts reproducing in other updates.  






Actual results:

The WebExtension's Iframe that is expected to inject into the webpage is not injected.
As a result, Extension's UI giving options to users is not shown.


Having a look at the console suggests there are multiple parsing error when the browser loads these 2 pages(if it might help  investgation).


Expected results:

Expected : Extension's IFrame should load/inject in the given 2 webpages and this intermittent issue should be fixed.
Component: Untriaged → WebExtensions: Untriaged
Product: Firefox → Toolkit
Summary: [FF WebExtension] Intermittently JQuery variable $ remains unloaded(undefined) preventing extension's IFrame injection into webpage (www.bbc.com and and http://money.cnn.com/). IFrame's injection code is defined in Content Script → Intermittently JQuery variable $ remains unloaded(undefined) preventing extension's IFrame injection into webpage (www.bbc.com and and http://money.cnn.com/). IFrame's injection code is defined in Content Script
It's impossible to say anything about what's going on here without seeing the add-on's code.
Have you tried without jQuery? jQuery is not written with webextensions in mind, so it may not handle the difference between web content and the extension context properly.
Hi Folks,

I am created a prototype of the issue that I am facing,

To reproduce : 

temporarily load the extension xpi via about:debugging route.

open any page, e.g google.com, click on the extension icon, Iframe will load and be visible (red border).

now open www.bbc.com or http://money.cnn.com/,  allow them to load , once they are loaded, click on extension icon,

You will find that the Iframe does not load.
You didn't actually attach the extension
Flags: needinfo?(sandees)
Attached file Test Extesnsion .xpi
Attaching the prototype extension xpi on which the bug reproduces.
Flags: needinfo?(sandees)
attached the extension.
Hm. It looks like we're somehow losing the expando object for the window wrapper on these sites.
Status: UNCONFIRMED → NEW
Ever confirmed: true
Component: WebExtensions: Untriaged → XPConnect
Product: Toolkit → Core
Summary: Intermittently JQuery variable $ remains unloaded(undefined) preventing extension's IFrame injection into webpage (www.bbc.com and and http://money.cnn.com/). IFrame's injection code is defined in Content Script → Expando object for Sandbox Window wrapper sometimes gets lost
Any Expected time frame in which this issue will be fixed?
(In reply to Acrobat from comment #8)
> Any Expected time frame in which this issue will be fixed?

No, but if you want a quick workaround, you can add something like `let $ = window.jQuery` to the start of your content script.
Thanks Kris,
Is using window.jQuery safe?
I must ensure that my extension uses it's own jQuery and not some other jQuery defined somewhere else in the web-page by some other page-script may be.
Will this statement return the jQuery loaded and defined by my extension?
Yes, it will be the jQuery loaded by your extension if I'm not mistaken. To verify my statement, you can use window.jQuery.fn.jquery to show the jQuery version that is loaded.
Priority: -- → P3
I need want to confirm here, is using the global object "window.jQuery" in my extension's content script safe?
Is is same as the sandboxed version of jQuery returned under content script execution environment.
And, if i go with the work around code suggested, will there be any implication/conflict when this issue is fixed?
Window.jquery, i guess will return the jquery associated with the global window object, that is same for all tabs. My web extension functions are tab specific. I do not want to use a jquery that is assigned in tab A and is being used in tab B. I will rather prefer wait for the fix, please suggest.
(In reply to Acrobat from comment #13)
> Window.jquery, i guess will return the jquery associated with the global
> window object, that is same for all tabs.

No. `window` is the window object for the window your content script is loaded into. The only thing my suggested workaround does is cache the jQuery object from the window's expando object in your lexical scope so that you still have access to it when the expando object is lost.
On
facebook.com ,
adblock plus is missing the "block element" feature when clicking on the addo icon
I guess I ran into this bug myself as well. I have a different scenario, without jQuery.
But with similar symptoms.

https://groups.google.com/forum/#!topic/mozilla.dev.platform/hookWGg0rfs

This simple web extension used to work on FF51 and still works on Google Chrome. 
But it no longer works reliably on FF57 when loading the content script for https://vk.com/. 
I get the following error: 

ReferenceError: Awesomplete is not defined  contentscript.js:464:5 

The extension adds an autocomplete input field to the webpage. It works on other pages, such as example.com. If you type "ja" in the box it suggest "JavaScript". 

But not on https://vk.com/. It doesn't work on money.cnn.com either, but works on bbc.com.

https://www.dropbox.com/s/7333ghu5qegvyjf/vkissue.xpi?dl=0 

Any idea for a solution/workaround in the case of Awesomplete?
(In reply to Kris Maglione [:kmag] (long backlog; ping on IRC if you're blocked) from comment #9)
> (In reply to Acrobat from comment #8)
> > Any Expected time frame in which this issue will be fixed?
> 
> No, but if you want a quick workaround, you can add something like `let $ =
> window.jQuery` to the start of your content script.

Would that be a safe workaround? Looks like a race condition to me. What if the page sets document.domain earlier than we can cache in the content script? As mentioned in this duplicate: https://bugzilla.mozilla.org/show_bug.cgi?id=1414783 setting document.domain causes losing the expando object for the window wrapper.

Because of this bug I removed dependency on jQuery from my extension and integrated the Awesomplete library into my content script so I wouldn't have to deal with losing access to these globals.
> Would that be a safe workaround?

Content scripts should (or, at least, are specced to) run before page scripts if requested in the manifest. You should be able to capture references when the scripts are first run, this being the case. Naturally, you will have to reference all of the global variables you have set via the captured local objects to get around this bug completely.

For any extension with changing global variables, you will need to use a shared proxy object, attended to the global object initially, and ensure that all uses of all variables go via that proxy object.


For reference, Vimium tries only to restore the values to the global context at opportune moments so that we can avoid a large code change, and the maintainance burden going forward. Occasionally, but expectedly, race conditions still reseult in a catastrophic failure for us.
Thanks! Gives me more confidence there's a way to workaround this bug. It's a nasty bug imho. Since content scripts are supposed to be sandboxed. But with this bug the scripts from the web page can interfere with the sandboxed content script. Probably makes lots of web extensions unreliable at the moment.
I was pointed to this bug from a Discourse page: https://discourse.mozilla.org/t/audio-element-losing-custom-properties/23013?u=jeenuv. I've a small extension reproducer with content script therein if there's a need for another one.
My extension Tridactyl ran into this bug too a while ago. Seeing as this bug probably won't be fixed for a while I've edited this wiki page to say that the global scope in content scripts can't be trusted:

https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Content_scripts
I also have recently run into the bug. It's a very bad bug in my opinion and you should try to fix it as soon as possible. I just can't extend the functionality of my extension due to the bug, since I use an application built with React.js, whose source code is minified and there are lots of "window.*" expressions.
It looks like this bug is why my content script running on Firefox 63.0.3 can't see (some of?) the usual automatic "Named access on the Window object" window properties:

 https://html.spec.whatwg.org/multipage/window-object.html#named-access-on-the-window-object

So if an iframe in the parent window is called "f", "parent.f" returns undefined rather than an iframe element, though both

parent.frames[0]   AND
parent.document.getElementById('f').contentWindow

can still be used by the content script to get the iframe's window.
Another reason besides Comment 23 and Comment 27 that this bug is bad, is that some extensions like mine provide a service that allows users to access arbitrary properties and execute arbitrary expressions. So I can't implement a work-around, only tell my users to implement work-arounds.
Wow wow wow this bug was a really tough one to catch. I noticed that when code is run with the assumption of being in the `window` context, it actually may be in a `Sandbox` object context, which causes certain references to "disappear".

For me, getting around this simply required me to explicitly assign the references to the window object. But jeez.. that was a tough one. Hope this helps someone else.

Oh boy.. I just got hit by this one on bbc.com which seems like a different issue. Previously, the scope of certain variables were consistently being lost. But now, on specific sites (eg. bbc.com, but not money.cnn.com for me), everything blows up, and references aren't available after a certain point.

They may have JS that is doing something, because initially upon load, those references are available, but then they're lost.

To my surprise I noticed today that this issue has been fixed - It works now in FF 64 without any errors on websites where we saw that was happening.

Can you guys check your extension and confirm

I just tested in 64.0.2 (64-bit) and it's still happening.

Depends on: 1514050

Now that bug 1514050 is fixed, could people please retest in a nightly?

I tested it and it is fixed. Followed the steps in https://bugzilla.mozilla.org/show_bug.cgi?id=1513274

(In reply to hanu6 from comment #38)

I tested it and it is fixed. Followed the steps in https://bugzilla.mozilla.org/show_bug.cgi?id=1513274

Great! Closing this.

Assignee: nobody → bzbarsky
Status: NEW → RESOLVED
Closed: 5 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla67
You need to log in before you can comment on or make changes to this bug.