Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Unwrapping window wrappers

79 views
Skip to first unread message

Matthew Gertner

unread,
Mar 20, 2012, 10:52:41 AM3/20/12
to
We have been porting an older extension previously implemented for
Firefox v3.6 to Firefox v11. The extension relies on being able to
match up windows from various sources to the tab that contains them by
using window.top. It seems like in the latest Firefox versions, we are
no longer able to compare the top windows reliably because some of
them are wrappers. I guess some new wrappers have been added for
security reasons since v3.6. We tried comparing
window.wrappedJSObject, but it seems like in some cases that is a
wrapper too. (In fact some windows have the value of wrappedJSObject
set to themselves.)

Is there a way to reliably get at the underlying JS object of a window
regardless of its provenance (DOM event target, associated window of
an HTTP request, etc.)? Or is there another way that we can test these
windows for equality without comparing the JS object identity?

Bobby Holley

unread,
Mar 20, 2012, 12:52:36 PM3/20/12
to Matthew Gertner, dev-pl...@lists.mozilla.org
On Tue, Mar 20, 2012 at 7:52 AM, Matthew Gertner
<matthew...@gmail.com>wrote:

> We have been porting an older extension previously implemented for
> Firefox v3.6 to Firefox v11. The extension relies on being able to
> match up windows from various sources to the tab that contains them by
> using window.top. It seems like in the latest Firefox versions, we are
> no longer able to compare the top windows reliably because some of
> them are wrappers. I guess some new wrappers have been added for
> security reasons since v3.6.


It's true that a lot of magic went into window wrapping for FF4 (ie, Brain
Transplants). But that should be more or less invisible to script code.
Identity comparisons should work.


> We tried comparing
> window.wrappedJSObject, but it seems like in some cases that is a
> wrapper too. (In fact some windows have the value of wrappedJSObject
> set to themselves.)
>

So, for objects in other comparments, .wrappedJSObject gives you a wrapper
that waives Xray vision. If your wrapper is already waived, it just returns
the same wrapper. Waivers have a separate identity. So
|myframe.contentWindow !== myframe.contentWindow.wrappedJSObject|, but
|myframe.contentWindow.wrappedJSObject ===
myframe.contentWindow.wrappedJSObject.wrappedJSObject|.

An important point is that waivers are transitively maintained. So if you
use .wrappedJSObject once, every wrapper you get from subsequent property
operations and method calls on that object will be waived.

So my guess is that you used .wrappedJSObject somewhere, and you're trying
to compare a waived wrapper to an unwaived wrapper. If that isn't the
issue, can you post a reduced testcase?

Cheers,
bholley

Ben Bucksch

unread,
Mar 20, 2012, 2:14:59 PM3/20/12
to
On 20.03.2012 17:52, Bobby Holley wrote:
> An important point is that waivers are transitively maintained.

Sorry, but I got confused with your extensive use of the words "waived"
and "waivers". Maybe it's because English is not my native language, but
I understand "waived" as "forgotten or "dropped", but "waivers" =
"forgetters" or "droppers" makes no sense to me. Could you explain more,
ideally without using the word "waive"? Thanks.

Blake Kaplan

unread,
Mar 20, 2012, 2:49:02 PM3/20/12
to dev-pl...@lists.mozilla.org
On 03/20/2012 07:14 PM, Ben Bucksch wrote:
> Sorry, but I got confused with your extensive use of the words "waived"
> and "waivers". Maybe it's because English is not my native language, but
> I understand "waived" as "forgotten or "dropped", but "waivers" =
> "forgetters" or "droppers" makes no sense to me. Could you explain more,
> ideally without using the word "waive"? Thanks.

The idea here is not too complicated, but the terminology has always
been a little messy...

By default, chrome code touching content receives Xray wrappers
(formerly called XPCNativeWrappers). That is normally enough for chrome
code (it provides access to DOM behaviors and methods). If, however,
chrome code needs closer access to the underlying object, then it waives
the Xray wrapping behavior and gets a new wrapper around the object
(whose existence is mostly invisible except for preventing security
bugs). We can refer to the new wrapper however we want; they were called
SJOWs for a while, but nobody liked that. They have a new name in the
source code that I won't even mention here because it's so wrong, but we
can also call them waivers.

The second point to make is that once you waive the Xray behavior (by
using XPCNativeWrapper.unwrap(object) or by using
object.wrappedJSObject) you waive Xray behavior for all objects you
access though the return value. Therefore, if I have
XPCNativeWrapper.uwnrap(xrayWrappedWindow).document.body.firstChild, the
firstChild would *not* show Xray behavior. So we can think of the second
type of wrappers as "waivers of Xray behavior".

For what it's worth, XPCNativeWrapper.unwrap is a good way of avoiding
the "oops, my object wasn't an Xray wrapper and my
object.wrappedJSObject is returning odd things" problem.

-Blake

Joshua Cranmer

unread,
Mar 20, 2012, 4:33:11 PM3/20/12
to
To clarify the terminology: "waive" is often used to mean to
"voluntarily give up". In this case, I believe it means you are giving
up some of the protection that the wrappers normally give you.

Ben Bucksch

unread,
Mar 20, 2012, 7:22:50 PM3/20/12
to
Thanks for the explanation. I was guessing that there's some unspoken
new concept behing "waivers", thanks for explaining that and what "Xray"
means (basically just the old wrappedJSObject, but I thought that was a
joke, not a real name).

Matthew Gertner

unread,
Mar 21, 2012, 4:19:03 AM3/21/12
to Bobby Holley, dev-pl...@lists.mozilla.org
On Mar 20, 2012, at 5:52 PM, Bobby Holley wrote:

> So my guess is that you used .wrappedJSObject somewhere, and you're trying to compare a waived wrapper to an unwaived wrapper. If that isn't the issue, can you post a reduced testcase?

Thanks for the explanation. I'm pretty sure that we ended up with two wrappedJSObjects that had different JS object identity and different security behavior (some properties were accessible in one but not in the other). I'll try to reproduce in a simpler test case to nail down whether there is a mistake in our code or some sort of Firefox issue.

Matt
0 new messages