Figuring out the behavior of WindowProxy in the face of non-configurable properties

classic Classic list List threaded Threaded
51 messages Options
123
Reply | Threaded
Open this post in threaded view
|

RE: Figuring out the behavior of WindowProxy in the face of non-configurable properties

Mark S. Miller-2

Hi Travis, I didn't follow. Could you expand, assuming less background knowledge?  Thanks.

On Jan 14, 2015 2:58 PM, "Travis Leithead" <[hidden email]> wrote:

WindowProxies are going to be a challenge when it comes to a pure ES implementation. The other challenge that just came to mind, is the document object—at least in Gecko and IE: a document.write call will “re-init” the object (subbing out the old var for a new one) while maintaining the === invariant. Chrome appears to have a simpler model for dealing with this. I’m not sure what HTML has to say about this currently…

 

From: Mark S. Miller [mailto:[hidden email]]
Sent: Wednesday, January 14, 2015 2:44 PM
To: Boris Zbarsky
Cc: Ian Hickson; Travis Leithead; Domenic Denicola; [hidden email]; es-discuss
Subject: Re: Figuring out the behavior of WindowProxy in the face of non-configurable properties

 

Boris has this exactly right. Further, a malicious proxy handler can leverage the presence of a single object that violates these invariants into the creation of arbitrary other proxies objects that also violate these invariants. The key is that the enforcement of the invariants relies on the proxy's target being constrained by these invariants.

 

 

 

 

On Wed, Jan 14, 2015 at 2:32 PM, Boris Zbarsky <[hidden email]> wrote:

On 1/14/15 3:17 PM, Ian Hickson wrote:

It's more than that. It's how the HTML spec defines WindowProxy.


The point is, the HTML spec's definition is not expressible in ES terms.  So how do go about bridging this gap?

According to the HTML spec, all operations that would be performed on the
WindowProxy object must be performed on the Window object of the browsing
context's active document instead. So the above would set a property on
the underlying Window object, not the WindowProxy.


It would call the [[DefineOwnProperty]] trap of the WindowProxy.  That then forwards to the Window, yes?

...but the window proxy's [[GetOwnProperty]] just forwards that straight
to the Window's [[GetOwnProperty]].


Yes, but since which window it forwards to changes you get an invariant violation for the WindowProxy object itself.

The property is on the Window, not the WindowProxy. It can't disappear
from the Window. The invariant is thus maintained.


I think you misunderstand what the invariant is.

There is no way to directly query the WindowProxy.


It doesn't matter.  The user sees the WindowProxy, not the Window. After you navigate, you still have the same WindowProxy (e.g. .contentWindow returns something that is === to the thing you had before you navigated).  But properties it claimed to have that were non-configurable are now gone.  That is precisely a violation of the invariants.

To all intents and purposes, it's not a real object.


It looks like an object and quacks like an object.  Sorry, but it's an object as far as all consumers are concerned; they have no way to tell it apart from an object except _maybe_ via these invariant violations. But then you've entered circular argument territory.

It's a reference to another object


JS doesn't have such a type in the language, sadly, so we can't model it that way for consumers.

-Boris



 

--

    Cheers,
    --MarkM


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

RE: Figuring out the behavior of WindowProxy in the face of non-configurable properties

Domenic Denicola
In reply to this post by Mark S. Miller-2
From: Travis Leithead [mailto:[hidden email]]

> WindowProxies are going to be a challenge when it comes to a pure ES implementation.

Shouldn't be too hard to implement a Direct Proxy that follows this proto-spec: https://github.com/domenic/window-proxy-spec

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Figuring out the behavior of WindowProxy in the face of non-configurable properties

Ian Hickson
In reply to this post by Mark S. Miller-2
On Wed, 14 Jan 2015, Boris Zbarsky wrote:
> On 1/14/15 3:17 PM, Ian Hickson wrote:
> > It's more than that. It's how the HTML spec defines WindowProxy.
>
> The point is, the HTML spec's definition is not expressible in ES terms.  
> So how do go about bridging this gap?

I don't understand what you mean by "expressible in ES terms".

It's expressed in English.


> > According to the HTML spec, all operations that would be performed on
> > the WindowProxy object must be performed on the Window object of the
> > browsing context's active document instead. So the above would set a
> > property on the underlying Window object, not the WindowProxy.
>
> It would call the [[DefineOwnProperty]] trap of the WindowProxy.  That
> then forwards to the Window, yes?

No. WindowProxy isn't an ES Proxy. (The term WindowProxy predates ES
Proxy). When you have a WindowProxy object, it acts exactly like the
Window object to which it currently points. It is indistinguishable from
the Window object. When the WindowProxy changes what it's pointing at,
it's exactly as if the browser had reached in and changed every
WindowProxy that pointed to the former and made it point to the latter.


> > ...but the window proxy's [[GetOwnProperty]] just forwards that
> > straight to the Window's [[GetOwnProperty]].
>
> Yes, but since which window it forwards to changes you get an invariant
> violation for the WindowProxy object itself.

I don't understand how that follows.


> > The property is on the Window, not the WindowProxy. It can't disappear
> > from the Window. The invariant is thus maintained.
>
> I think you misunderstand what the invariant is.

Maybe. Please elaborate.


> > There is no way to directly query the WindowProxy.
>
> It doesn't matter.  The user sees the WindowProxy, not the Window.

No. What the author has is a WindowProxy, but in every sense it acts like
a Window. (Which Window it acts like changes occasionally.)


> After you navigate, you still have the same WindowProxy (e.g.
> .contentWindow returns something that is === to the thing you had before
> you navigated).

You have no way to actually test this. Since every reference to the old
Window is now a reference to the new Window, you have no way to test if
the WindowProxy references something new. It's just like if the browser
had reached in and changed all your references from under you.


> But properties it claimed to have that were non-configurable are now
> gone.  That is precisely a violation of the invariants.

Suppose you have this code:

   // part 1
   let a = {};
   let b = {};
   let c = a;

   // part 2
   c.foo = 1;

   // part 3
   c = b;

   // part 4
   console.log(c.foo);

Is it surprising that the log doesn't log "1"?

This is what is going on here, except that part 3 is done by the browser.


> > To all intents and purposes, it's not a real object.
>
> It looks like an object and quacks like an object.

It looks and quacks like a Window.


> > It's a reference to another object
>
> JS doesn't have such a type in the language, sadly, so we can't model it
> that way for consumers.

It turns out that it does have such a type. WindowProxy is it. I agree
that that makes it a special snowflake.



On Wed, 14 Jan 2015, Mark S. Miller wrote:
>
> Boris has this exactly right. Further, a malicious proxy handler can
> leverage the presence of a single object that violates these invariants
> into the creation of arbitrary other proxies objects that also violate
> these invariants. The key is that the enforcement of the invariants
> relies on the proxy's target being constrained by these invariants.
>
> See http://research.google.com/pubs/pub40736.html

If you're exposing your Window object to untrusted code you are so far
beyond losing that this is the least of your concerns.

--
Ian Hickson               U+1047E                )\._.,--....,'``.    fL
http://ln.hixie.ch/       U+263A                /,   _.. \   _\  ;`._ ,.
Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Figuring out the behavior of WindowProxy in the face of non-configurable properties

Boris Zbarsky
In reply to this post by Mark S. Miller-2
On 1/14/15 5:58 PM, Travis Leithead wrote:
> The other challenge that just came to mind, is the
> document object—at least in Gecko and IE: a document.write call will
> “re-init” the object (subbing out the old var for a new one)

What Gecko does on document.open is just create a new Window, just like
navigation.  This part is actually pretty clearly defined in the HTML spec.

-Boris
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Figuring out the behavior of WindowProxy in the face of non-configurable properties

Boris Zbarsky
In reply to this post by Ian Hickson
On 1/14/15 7:40 PM, Ian Hickson wrote:
> I don't understand what you mean by "expressible in ES terms".

The behavior of ES objects is expressed in terms of various internal
methods.  That's what you have to do to express what an ES object does.

> No. WindowProxy isn't an ES Proxy.

It's an ES object.

> It is indistinguishable from the Window object.

It's distinguishable in various ways, including things like "if I get
this property from it in 5 seconds, will I get the same value as from
the Window?"  The answer to that is "maybe not".

> When the WindowProxy changes what it's pointing at,
> it's exactly as if the browser had reached in and changed every
> WindowProxy that pointed to the former and made it point to the latter.

You say "every WindowProxy", but in practice in an ES implementation you
have some object, it has some internal methods.  This is the last time
I'm bothering to go through this with you, since clearly we're getting
nowhere, as I said in https://www.w3.org/Bugs/Public/show_bug.cgi?id=27128

> I don't understand how that follows.

I don't understand how you can possibly not understand, except via your
assumption that a WindowProxy is not an object.

>> I think you misunderstand what the invariant is.
>
> Maybe. Please elaborate.

The internal methods of every object must have behavior that preserves
the invariants.

For ES proxies, the internal methods are defined in the spec in a way
that preserves the invariant.

For other ES objects they are also defined in the spec.

ES also allows other "exotic objects" that define some other behavior
for those internal methods, but requires that the invariants be preserved.

>> It doesn't matter.  The user sees the WindowProxy, not the Window.
>
> No. What the author has is a WindowProxy, but in every sense it acts like
> a Window.

You mean in every sense except what property values you'll get five
seconds from now.

But again, we agree the author has a WindowProxy.  Good.

>> After you navigate, you still have the same WindowProxy (e.g.
>> .contentWindow returns something that is === to the thing you had before
>> you navigated).
>
> You have no way to actually test this. Since every reference to the old
> Window is now a reference to the new Window, you have no way to test if
> the WindowProxy references something new.

=== on objects tests object identity.  It's not affected by internal
methods in any way.  Therefore, if === returns true then you actually
have the same object.

>     // part 1
>     let a = {};
>     let b = {};
>     let c = a;
>
>     // part 2
>     c.foo = 1;
>
>     // part 3
>     c = b;
>
>     // part 4
>     console.log(c.foo);
>
> Is it surprising that the log doesn't log "1"?

None of this affects the invariants involved.

> This is what is going on here, except that part 3 is done by the browser.

No, because in the code above if I do |var d = c;| then the d won't
change in part 3.  Having an object with sane internal methods here is
really much simpler than magic "update all the references" behavior.
But again, I've said this to you numerous times.

Let me try it again: the fact that the definition in the HTML spec has
not lead to interop is not an accident.  It's not something browsers can
sanely achieve interop on because it involves handwavy magic that they
are extremely likely to interpret differently.  On the other hand,
defining a single object with internal methods that do what you want
would be _very_ clear to an DOM or JS engine implementor.

> It looks and quacks like a Window.

No, it, doesn't, see above.

> It turns out that it does have such a type. WindowProxy is it. I agree
> that that makes it a special snowflake.

My point is that this special snowflake is unnecessary and confusing.

-Boris
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Figuring out the behavior of WindowProxy in the face of non-configurable properties

Bjoern Hoehrmann
* Boris Zbarsky wrote:
>You say "every WindowProxy", but in practice in an ES implementation you
>have some object, it has some internal methods.  This is the last time
>I'm bothering to go through this with you, since clearly we're getting
>nowhere, as I said in https://www.w3.org/Bugs/Public/show_bug.cgi?id=27128

What are the odds that the behavior observable by web pages can actually
be defined sanely such that ES invariants and compatibility requirements
are satisfied? https://www.w3.org/Bugs/Public/show_bug.cgi?id=27128#c15
indicates, as I understand it, the odds may be quite good. In that case,
looking for a volunteer to come up with a proposal might be a good next
step.
--
Björn Höhrmann · mailto:[hidden email] · http://bjoern.hoehrmann.de
D-10243 Berlin · PGP Pub. KeyID: 0xA4357E78 · http://www.bjoernsworld.de
 Available for hire in Berlin (early 2015)  · http://www.websitedev.de/ 
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Figuring out the behavior of WindowProxy in the face of non-configurable properties

Mark S. Miller-2
Domenic's https://github.com/domenic/window-proxy-spec seems headed in the right direction. I suggest starting there. 

Test proposals by self-hosting in ES6. Such self hosting would use direct proxies *not* because the term "proxy" in WindowProxy has any historical relation -- it does not -- but because the rest of ES6 is not powerful enough to self-host its behavior.




On Wed, Jan 14, 2015 at 5:56 PM, Bjoern Hoehrmann <[hidden email]> wrote:
* Boris Zbarsky wrote:
>You say "every WindowProxy", but in practice in an ES implementation you
>have some object, it has some internal methods.  This is the last time
>I'm bothering to go through this with you, since clearly we're getting
>nowhere, as I said in https://www.w3.org/Bugs/Public/show_bug.cgi?id=27128

What are the odds that the behavior observable by web pages can actually
be defined sanely such that ES invariants and compatibility requirements
are satisfied? https://www.w3.org/Bugs/Public/show_bug.cgi?id=27128#c15
indicates, as I understand it, the odds may be quite good. In that case,
looking for a volunteer to come up with a proposal might be a good next
step.
--
Björn Höhrmann · mailto:[hidden email] · http://bjoern.hoehrmann.de
D-10243 Berlin · PGP Pub. KeyID: 0xA4357E78 · http://www.bjoernsworld.de
 Available for hire in Berlin (early 2015)  · http://www.websitedev.de/



--
    Cheers,
    --MarkM

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Figuring out the behavior of WindowProxy in the face of non-configurable properties

Boris Zbarsky
In reply to this post by Mark S. Miller-2
On 1/14/15 8:49 PM, Travis Leithead wrote:
> and existing elements and their document are disconnected from the
> window, while a new document and the new elements created from parsing
> are put in their place.

More precisely, the old elements are disconnected from the document, the
document is disconnected from the window, and the document is connected
to the new window.

> Implementations differ on how they handle the scenario. Boris notes that
> Gecko just creates a new window (with a new document, etc.)

No, it's the same document.

> Boris can correct me if I got this wrong.

You got it wrong.  ;)

-Boris
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Figuring out the behavior of WindowProxy in the face of non-configurable properties

Boris Zbarsky
In reply to this post by Bjoern Hoehrmann
On 1/14/15 8:56 PM, Bjoern Hoehrmann wrote:
> What are the odds that the behavior observable by web pages can actually
> be defined sanely such that ES invariants and compatibility requirements
> are satisfied?

My personal best estimate is about 30% chance for the one such
definition we have so far being web compatible.  But this is mostly
based on gut feeling.

> https://www.w3.org/Bugs/Public/show_bug.cgi?id=27128#c15
> indicates, as I understand it, the odds may be quite good. In that case,
> looking for a volunteer to come up with a proposal might be a good next
> step.

We have a proposal.  It's at https://github.com/domenic/window-proxy-spec

I have an implementation that I've been trying to land in Firefox for a
few weeks.  I had to fix a bunch of our tests, then restrict the change
to web pages because it breaks various extensions.  I'm pretty hopeful
that I can at least get it to the point where I can try doing some web
compat testing...

https://bugzilla.mozilla.org/show_bug.cgi?id=1107443 for those who want
to follow along.

-Boris

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Figuring out the behavior of WindowProxy in the face of non-configurable properties

Ian Hickson
In reply to this post by Boris Zbarsky
On Wed, 14 Jan 2015, Boris Zbarsky wrote:
>
> The behavior of ES objects is expressed in terms of various internal methods.
> That's what you have to do to express what an ES object does.

Not necessarily. We can also just say "WindowProxy is its own thing and
here is how it works".


> > No. WindowProxy isn't an ES Proxy.
>
> It's an ES object.

That's debatable.


> > It is indistinguishable from the Window object.
>
> It's distinguishable in various ways, including things like "if I get
> this property from it in 5 seconds, will I get the same value as from
> the Window?" The answer to that is "maybe not".

No, because by the time it returns a different value, it no longer acts
like it's the same object.

You're holding a magical thing that looks and acts exactly like a potted
plant. It's indistinguishable from a potted plant. Then five seconds
later, you're holding a cat. It's indistinguishable from a cat. You can't
tell that the potted plant and the cat are the same thing. You can presume
that since you were holding one, and then you were holding the other, they
might have some relationship, but there's no way to tell that they're the
same thing. Even if the assume they're the same thing, you can't tell the
difference between the being the same thing, and someone just quickly
stealing the potted plant and replacing it with a cat.


> > When the WindowProxy changes what it's pointing at, it's exactly as if
> > the browser had reached in and changed every WindowProxy that pointed
> > to the former and made it point to the latter.
>
> You say "every WindowProxy", but in practice in an ES implementation you
> have some object, it has some internal methods.  This is the last time
> I'm bothering to go through this with you, since clearly we're getting
> nowhere, as I said in
> https://www.w3.org/Bugs/Public/show_bug.cgi?id=27128

You are dismissing what I'm describing as being a misunderstanding of how
things should be considered to work, because they're not the same as what
you're describing. But maybe what I'm describing is how things should be
considered to work, and what you're describing is wrong. Or maybe both our
points of view are valid, and we should figure out which is easiest to
describe, or easiest to implement, or simplest to explain to authors, or
most compatible with the Web, or least likely to involve contortions
around unnecessary invariants, or whatever other priorities we want to
apply to this decision.


> The internal methods of every object must have behavior that preserves
> the invariants.
>
> For ES proxies, the internal methods are defined in the spec in a way
> that preserves the invariant.
>
> For other ES objects they are also defined in the spec.
>
> ES also allows other "exotic objects" that define some other behavior
> for those internal methods, but requires that the invariants be
> preserved.

So one option would be to just say that WindowProxy is not an ES object.


> > > It doesn't matter.  The user sees the WindowProxy, not the Window.
> >
> > No. What the author has is a WindowProxy, but in every sense it acts
> > like a Window.
>
> You mean in every sense except what property values you'll get five
> seconds from now.

Five seconds from now, the author will in every sense appear to have a
different Window. It still appears to be a Window. Just a different one.


> > > After you navigate, you still have the same WindowProxy (e.g.
> > > .contentWindow returns something that is === to the thing you had
> > > before you navigated).
> >
> > You have no way to actually test this. Since every reference to the
> > old Window is now a reference to the new Window, you have no way to
> > test if the WindowProxy references something new.
>
> === on objects tests object identity.

Except on WindowProxy, because WindowProxy forwards all operations to the
underlying Window.


> It's not affected by internal methods in any way.  Therefore, if ===
> returns true then you actually have the same object.

Consider:

   let a = {};
   let b = {};

   let c = a;
   let d = a;

   assert(c === d); // true

   opaqueCode();

   assert(c === d); // still true

If the opaqueCode() function just does:

   function opaqueCode() {
     c = b;
     d = b;
   }

...then === doesn't help you tell that c and d have changed identity. They
are still triple-equals to each other, but they're different objects.

This is exactly what happens with WindowProxy, except that the browser is
the code doing opaqueCode().
   

> >     // part 1
> >     let a = {};
> >     let b = {};
> >     let c = a;
> >
> >     // part 2
> >     c.foo = 1;
> >
> >     // part 3
> >     c = b;
> >
> >     // part 4
> >     console.log(c.foo);
> >
> > Is it surprising that the log doesn't log "1"?
>
> None of this affects the invariants involved.

The point is that the invariants apply to the actual objects originally
assigned to a and b, they don't apply to the variables.


> > This is what is going on here, except that part 3 is done by the
> > browser.
>
> No, because in the code above if I do |var d = c;| then the d won't
> change in part 3.

If in the code above you do var d = c, then add d = b to part 3 to
simulate what the browser does.


> Having an object with sane internal methods here is really much simpler
> than magic "update all the references" behavior. But again, I've said
> this to you numerous times.

I'm not actually proposing updating all the references. That's just a
convenient way to think about it that is isomorphic in behaviour to what
is specced. What is specced is just that you have a placeholder
pseudo-object that forwards all behaviour to an underlying object, where
which object it's forwarding to can change over time.


> Let me try it again: the fact that the definition in the HTML spec has
> not lead to interop is not an accident.  It's not something browsers can
> sanely achieve interop on because it involves handwavy magic that they
> are extremely likely to interpret differently.  On the other hand,
> defining a single object with internal methods that do what you want
> would be _very_ clear to an DOM or JS engine implementor.

I have asked before, but would like to reiterate:

If there is any behaviour that is underdefined by the HTML spec's current
prose, please tell me, so that I can spec it.


> > It looks and quacks like a Window.
>
> No, it, doesn't, see above.

It is literally indistinguishable from _a_ Window in every way at all
times. That's the whole point. Which Window it appears to be
indistinguishable from at any particular time varies over time.


> > It turns out that it does have such a type. WindowProxy is it. I agree
> > that that makes it a special snowflake.
>
> My point is that this special snowflake is unnecessary and confusing.

Well it predates all the ES6 stuff we're talking about here by several
years, so I'd argue that the confusion doesn't stem from WindowProxy. I
also don't really agree that it's confusing. It's really simple to
explain, certainly much simpler than anything involving ES proxies and so
forth. It's one sentence in the spec, and as far as I'm aware, it doesn't
leave anything undefined.

I also disagree that what the spec says doesn't match implementations. I
think it matches implementations pretty darn closely. I mean, in
particular, it matches exactly what Travis described as IE's
implementation. (This is not an accident; matching implementations was one
of the main goals of the HTML spec, and at the time this was specced, IE
was by far the biggest UA out there.)

--
Ian Hickson               U+1047E                )\._.,--....,'``.    fL
http://ln.hixie.ch/       U+263A                /,   _.. \   _\  ;`._ ,.
Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Figuring out the behavior of WindowProxy in the face of non-configurable properties

Yehuda Katz

bz said:

> ES also allows other "exotic objects" that define some other behavior
> for those internal methods, but requires that the invariants be
> preserved.

Hixie said:

So one option would be to just say that WindowProxy is not an ES object. 

---

If it's available to JavaScript consumers it must look like an object that obeys ES invariants to JavaScript consumers. No (new, ugh) exceptions.


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Figuring out the behavior of WindowProxy in the face of non-configurable properties

Filip Pizlo
In reply to this post by Ian Hickson

> On Jan 14, 2015, at 7:14 PM, Ian Hickson <[hidden email]> wrote:
>
> On Wed, 14 Jan 2015, Boris Zbarsky wrote:
>>
>> The behavior of ES objects is expressed in terms of various internal methods.
>> That's what you have to do to express what an ES object does.
>
> Not necessarily. We can also just say "WindowProxy is its own thing and
> here is how it works".
>
>
>>> No. WindowProxy isn't an ES Proxy.
>>
>> It's an ES object.
>
> That's debatable.
>
>
>>> It is indistinguishable from the Window object.
>>
>> It's distinguishable in various ways, including things like "if I get
>> this property from it in 5 seconds, will I get the same value as from
>> the Window?" The answer to that is "maybe not".
>
> No, because by the time it returns a different value, it no longer acts
> like it's the same object.
>
> You're holding a magical thing that looks and acts exactly like a potted
> plant. It's indistinguishable from a potted plant. Then five seconds
> later, you're holding a cat. It's indistinguishable from a cat. You can't
> tell that the potted plant and the cat are the same thing. You can presume
> that since you were holding one, and then you were holding the other, they
> might have some relationship, but there's no way to tell that they're the
> same thing. Even if the assume they're the same thing, you can't tell the
> difference between the being the same thing, and someone just quickly
> stealing the potted plant and replacing it with a cat.
>
>
>>> When the WindowProxy changes what it's pointing at, it's exactly as if
>>> the browser had reached in and changed every WindowProxy that pointed
>>> to the former and made it point to the latter.
>>
>> You say "every WindowProxy", but in practice in an ES implementation you
>> have some object, it has some internal methods.  This is the last time
>> I'm bothering to go through this with you, since clearly we're getting
>> nowhere, as I said in
>> https://www.w3.org/Bugs/Public/show_bug.cgi?id=27128
>
> You are dismissing what I'm describing as being a misunderstanding of how
> things should be considered to work, because they're not the same as what
> you're describing. But maybe what I'm describing is how things should be
> considered to work, and what you're describing is wrong. Or maybe both our
> points of view are valid, and we should figure out which is easiest to
> describe, or easiest to implement, or simplest to explain to authors, or
> most compatible with the Web, or least likely to involve contortions
> around unnecessary invariants, or whatever other priorities we want to
> apply to this decision.
>
>
>> The internal methods of every object must have behavior that preserves
>> the invariants.
>>
>> For ES proxies, the internal methods are defined in the spec in a way
>> that preserves the invariant.
>>
>> For other ES objects they are also defined in the spec.
>>
>> ES also allows other "exotic objects" that define some other behavior
>> for those internal methods, but requires that the invariants be
>> preserved.
>
> So one option would be to just say that WindowProxy is not an ES object.
>
>
>>>> It doesn't matter.  The user sees the WindowProxy, not the Window.
>>>
>>> No. What the author has is a WindowProxy, but in every sense it acts
>>> like a Window.
>>
>> You mean in every sense except what property values you'll get five
>> seconds from now.
>
> Five seconds from now, the author will in every sense appear to have a
> different Window. It still appears to be a Window. Just a different one.
>
>
>>>> After you navigate, you still have the same WindowProxy (e.g.
>>>> .contentWindow returns something that is === to the thing you had
>>>> before you navigated).
>>>
>>> You have no way to actually test this. Since every reference to the
>>> old Window is now a reference to the new Window, you have no way to
>>> test if the WindowProxy references something new.
>>
>> === on objects tests object identity.
>
> Except on WindowProxy, because WindowProxy forwards all operations to the
> underlying Window.
>
>
>> It's not affected by internal methods in any way.  Therefore, if ===
>> returns true then you actually have the same object.
>
> Consider:
>
>   let a = {};
>   let b = {};
>
>   let c = a;
>   let d = a;
>
>   assert(c === d); // true
>
>   opaqueCode();
>
>   assert(c === d); // still true
>
> If the opaqueCode() function just does:
>
>   function opaqueCode() {
>     c = b;
>     d = b;
>   }
>
> ...then === doesn't help you tell that c and d have changed identity. They
> are still triple-equals to each other, but they're different objects.

Are you saying that it’s easier to spec having the browser find all variables (local or otherwise) that reference some object and replace them with references to a different object?

>
> This is exactly what happens with WindowProxy, except that the browser is
> the code doing opaqueCode().
>
>
>>>    // part 1
>>>    let a = {};
>>>    let b = {};
>>>    let c = a;
>>>
>>>    // part 2
>>>    c.foo = 1;
>>>
>>>    // part 3
>>>    c = b;
>>>
>>>    // part 4
>>>    console.log(c.foo);
>>>
>>> Is it surprising that the log doesn't log "1"?
>>
>> None of this affects the invariants involved.
>
> The point is that the invariants apply to the actual objects originally
> assigned to a and b, they don't apply to the variables.
>
>
>>> This is what is going on here, except that part 3 is done by the
>>> browser.
>>
>> No, because in the code above if I do |var d = c;| then the d won't
>> change in part 3.
>
> If in the code above you do var d = c, then add d = b to part 3 to
> simulate what the browser does.
>
>
>> Having an object with sane internal methods here is really much simpler
>> than magic "update all the references" behavior. But again, I've said
>> this to you numerous times.
>
> I'm not actually proposing updating all the references. That's just a
> convenient way to think about it that is isomorphic in behaviour to what
> is specced. What is specced is just that you have a placeholder
> pseudo-object that forwards all behaviour to an underlying object, where
> which object it's forwarding to can change over time.
>
>
>> Let me try it again: the fact that the definition in the HTML spec has
>> not lead to interop is not an accident.  It's not something browsers can
>> sanely achieve interop on because it involves handwavy magic that they
>> are extremely likely to interpret differently.  On the other hand,
>> defining a single object with internal methods that do what you want
>> would be _very_ clear to an DOM or JS engine implementor.
>
> I have asked before, but would like to reiterate:
>
> If there is any behaviour that is underdefined by the HTML spec's current
> prose, please tell me, so that I can spec it.
>
>
>>> It looks and quacks like a Window.
>>
>> No, it, doesn't, see above.
>
> It is literally indistinguishable from _a_ Window in every way at all
> times. That's the whole point. Which Window it appears to be
> indistinguishable from at any particular time varies over time.
>
>
>>> It turns out that it does have such a type. WindowProxy is it. I agree
>>> that that makes it a special snowflake.
>>
>> My point is that this special snowflake is unnecessary and confusing.
>
> Well it predates all the ES6 stuff we're talking about here by several
> years, so I'd argue that the confusion doesn't stem from WindowProxy. I
> also don't really agree that it's confusing. It's really simple to
> explain, certainly much simpler than anything involving ES proxies and so
> forth. It's one sentence in the spec, and as far as I'm aware, it doesn't
> leave anything undefined.
>
> I also disagree that what the spec says doesn't match implementations. I
> think it matches implementations pretty darn closely. I mean, in
> particular, it matches exactly what Travis described as IE's
> implementation. (This is not an accident; matching implementations was one
> of the main goals of the HTML spec, and at the time this was specced, IE
> was by far the biggest UA out there.)
>
> --
> Ian Hickson               U+1047E                )\._.,--....,'``.    fL
> http://ln.hixie.ch/       U+263A                /,   _.. \   _\  ;`._ ,.
> Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'
> _______________________________________________
> es-discuss mailing list
> [hidden email]
> https://mail.mozilla.org/listinfo/es-discuss

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Figuring out the behavior of WindowProxy in the face of non-configurable properties

Boris Zbarsky
In reply to this post by Ian Hickson
On 1/14/15 10:14 PM, Ian Hickson wrote:
> You are dismissing what I'm describing as being a misunderstanding of how
> things should be considered to work,

No, I'm dismissing it as introducing magic that doesn't need to be
introduced and hence making the platform more complicate than it needs
to be, for no benefit I can perceive.

I do understand what you're describing, believe me.  I just have no
plans to implement it or ask anyone else to implement it.

> Or maybe both our
> points of view are valid, and we should figure out which is easiest to
> describe, or easiest to implement, or simplest to explain to authors, or
> most compatible with the Web, or least likely to involve contortions
> around unnecessary invariants, or whatever other priorities we want to
> apply to this decision.

Yes, that's what I've been saying all along.

I will claim that my description is easier to describe rigorously,
easier to implement, probably just as nasty to explain to authors, can
completely replicate the observable behavior of your description if
needed (e.g. by just directly forwarding all internal methods to the
Window, at the cost of violating the invariants this thread is about),
so can be just as compatible with the web, and gives at least a chance
of preserving invariants people care about if that's what people want to do.

Whereas your description basically forecloses all discussion on how
things should behave, because it locks them in to behaving in the single
way you like; doing any other behavior requires going to a different model.

>> ES also allows other "exotic objects" that define some other behavior
>> for those internal methods, but requires that the invariants be
>> preserved.
>
> So one option would be to just say that WindowProxy is not an ES object.

You were talking about explaining something to authors or making it
implementable, yes?

> Except on WindowProxy, because WindowProxy forwards all operations to the
> underlying Window.

There is no "operation" to forward here.  === is literally just bitwise
memory comparison equality in implementations.

> If the opaqueCode() function just does:
>
>     function opaqueCode() {
>       c = b;
>       d = b;

It doesn't have c and d in its scope, so can't do that.

And yes, you're going to say that the browser has everything "in scope",
but the point is that your model involves some sort of non-local
complicated heap-walking effect whereas changing the target of a proxy
... not that.

> The point is that the invariants apply to the actual objects originally
> assigned to a and b, they don't apply to the variables.

"variables" don't even exist as a useful concept by the time you're
running the code.  You've got values on the heap, on the stack, in
registers, etc, etc.  Just saying.

>> No, because in the code above if I do |var d = c;| then the d won't
>> change in part 3.
>
> If in the code above you do var d = c, then add d = b to part 3 to
> simulate what the browser does.

Yes, I know that's your mental model.  My point is that no sane
implementation would possibly want to actually implement it that way,
whereas implementing it in terms of internal methods is what at least
some implementations actually do.

> I'm not actually proposing updating all the references. That's just a
> convenient way to think about it

Except it's not a convenient way to think about it!

> What is specced is just that you have a placeholder
> pseudo-object

Why is it a pseudo-object when an object would do?

> I have asked before, but would like to reiterate:
>
> If there is any behaviour that is underdefined by the HTML spec's current
> prose, please tell me, so that I can spec it.

Care to ask the UA implementors who are clearly not doing anything even
resembling your spec?  Because it might turn out they might have reasons
for it...

> Well it predates all the ES6 stuff we're talking about here by several
> years

All the "stuff" involved was in ES5.  It's not new in ES6.  I've also
pointed this out to you several times now.

> it doesn't leave anything undefined.

Implementations seem to disagree by their actions, sadly.

> I also disagree that what the spec says doesn't match implementations.

Uh... Have you _tried_ testing this stuff in Safari?  I have; please see
archives for the results.  They look nothing like your spec.

-Boris
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Figuring out the behavior of WindowProxy in the face of non-configurable properties

Mark S. Miller-2
In reply to this post by Ian Hickson
On Wed, Jan 14, 2015 at 7:14 PM, Ian Hickson <[hidden email]> wrote:
On Wed, 14 Jan 2015, Boris Zbarsky wrote:
>
> The behavior of ES objects is expressed in terms of various internal methods.
> That's what you have to do to express what an ES object does.

Not necessarily. We can also just say "WindowProxy is its own thing and
here is how it works".


> > No. WindowProxy isn't an ES Proxy.
>
> It's an ES object.

That's debatable.

In the sense that we're debating it, sure.

WindowProxy is however a first class value observable by JS code, and therefore covered by the ES specs. Further, the various meta-object operations like Object.defineProperty accept it as an argument. If it isn't even an object, why is it observable all? Why do methods specified to operate on object arguments even accept it? Starting from your stance, I'd argue that all these operations should at least reject it with a TypeError.

Neither does the magic replacement theory excuse it from violating the spec. See https://mail.mozilla.org/pipermail/es-discuss/2011-May/014150.html , where we first clarified the difference between momentary and eternal invariants. Let's test the invariant stated in that message as

The ES5 constraints on updating non configurable properties are eternal invariants.

by writing test2c, in the same spirit as test2a and test2b:

(function(){"use strict";

// assume "gopd" & "is" initialization runs first, so these are 
// the original functions.
var gopd = Object.getOwnPropertyDescriptor;
var is = Object.is;

function test2c(obj, name, interleave) {
  name = String(name);
  var desc1 = gopd(obj, name);
  interleave();
  var desc2 = gopd(obj, name);
  if (!desc1.configurable) {
    assertFalse(desc2.configurable);
    assertTrue(desc2.enumerable === desc2.enumerable);
    if (gopd(desc1, 'writable') && !desc1.writable) {
      assertFalse(desc2.writable);
      assertTrue(is(desc1.value, desc2.value));
    }
  }
}

return test2c;

}());

In a conforming ES6 implementation (or a conforming ES5 one given the std "is" polyfill), it must not be possible to call test2c such that these asserts fail. No where do these specs say "unless interleave() replaces all pointers to obj to point at a different object". If it did, the whole notion of eternal invariants would be nonsense.






> > It is indistinguishable from the Window object.
>
> It's distinguishable in various ways, including things like "if I get
> this property from it in 5 seconds, will I get the same value as from
> the Window?" The answer to that is "maybe not".

No, because by the time it returns a different value, it no longer acts
like it's the same object.

You're holding a magical thing that looks and acts exactly like a potted
plant. It's indistinguishable from a potted plant. Then five seconds
later, you're holding a cat. It's indistinguishable from a cat. You can't
tell that the potted plant and the cat are the same thing. You can presume
that since you were holding one, and then you were holding the other, they
might have some relationship, but there's no way to tell that they're the
same thing. Even if the assume they're the same thing, you can't tell the
difference between the being the same thing, and someone just quickly
stealing the potted plant and replacing it with a cat.


> > When the WindowProxy changes what it's pointing at, it's exactly as if
> > the browser had reached in and changed every WindowProxy that pointed
> > to the former and made it point to the latter.
>
> You say "every WindowProxy", but in practice in an ES implementation you
> have some object, it has some internal methods.  This is the last time
> I'm bothering to go through this with you, since clearly we're getting
> nowhere, as I said in
> https://www.w3.org/Bugs/Public/show_bug.cgi?id=27128

You are dismissing what I'm describing as being a misunderstanding of how
things should be considered to work, because they're not the same as what
you're describing. But maybe what I'm describing is how things should be
considered to work, and what you're describing is wrong. Or maybe both our
points of view are valid, and we should figure out which is easiest to
describe, or easiest to implement, or simplest to explain to authors, or
most compatible with the Web, or least likely to involve contortions
around unnecessary invariants, or whatever other priorities we want to
apply to this decision.


> The internal methods of every object must have behavior that preserves
> the invariants.
>
> For ES proxies, the internal methods are defined in the spec in a way
> that preserves the invariant.
>
> For other ES objects they are also defined in the spec.
>
> ES also allows other "exotic objects" that define some other behavior
> for those internal methods, but requires that the invariants be
> preserved.

So one option would be to just say that WindowProxy is not an ES object.


> > > It doesn't matter.  The user sees the WindowProxy, not the Window.
> >
> > No. What the author has is a WindowProxy, but in every sense it acts
> > like a Window.
>
> You mean in every sense except what property values you'll get five
> seconds from now.

Five seconds from now, the author will in every sense appear to have a
different Window. It still appears to be a Window. Just a different one.


> > > After you navigate, you still have the same WindowProxy (e.g.
> > > .contentWindow returns something that is === to the thing you had
> > > before you navigated).
> >
> > You have no way to actually test this. Since every reference to the
> > old Window is now a reference to the new Window, you have no way to
> > test if the WindowProxy references something new.
>
> === on objects tests object identity.

Except on WindowProxy, because WindowProxy forwards all operations to the
underlying Window.


> It's not affected by internal methods in any way.  Therefore, if ===
> returns true then you actually have the same object.

Consider:

   let a = {};
   let b = {};

   let c = a;
   let d = a;

   assert(c === d); // true

   opaqueCode();

   assert(c === d); // still true

If the opaqueCode() function just does:

   function opaqueCode() {
     c = b;
     d = b;
   }

...then === doesn't help you tell that c and d have changed identity. They
are still triple-equals to each other, but they're different objects.

This is exactly what happens with WindowProxy, except that the browser is
the code doing opaqueCode().


> >     // part 1
> >     let a = {};
> >     let b = {};
> >     let c = a;
> >
> >     // part 2
> >     c.foo = 1;
> >
> >     // part 3
> >     c = b;
> >
> >     // part 4
> >     console.log(c.foo);
> >
> > Is it surprising that the log doesn't log "1"?
>
> None of this affects the invariants involved.

The point is that the invariants apply to the actual objects originally
assigned to a and b, they don't apply to the variables.


> > This is what is going on here, except that part 3 is done by the
> > browser.
>
> No, because in the code above if I do |var d = c;| then the d won't
> change in part 3.

If in the code above you do var d = c, then add d = b to part 3 to
simulate what the browser does.


> Having an object with sane internal methods here is really much simpler
> than magic "update all the references" behavior. But again, I've said
> this to you numerous times.

I'm not actually proposing updating all the references. That's just a
convenient way to think about it that is isomorphic in behaviour to what
is specced. What is specced is just that you have a placeholder
pseudo-object that forwards all behaviour to an underlying object, where
which object it's forwarding to can change over time.


> Let me try it again: the fact that the definition in the HTML spec has
> not lead to interop is not an accident.  It's not something browsers can
> sanely achieve interop on because it involves handwavy magic that they
> are extremely likely to interpret differently.  On the other hand,
> defining a single object with internal methods that do what you want
> would be _very_ clear to an DOM or JS engine implementor.

I have asked before, but would like to reiterate:

If there is any behaviour that is underdefined by the HTML spec's current
prose, please tell me, so that I can spec it.


> > It looks and quacks like a Window.
>
> No, it, doesn't, see above.

It is literally indistinguishable from _a_ Window in every way at all
times. That's the whole point. Which Window it appears to be
indistinguishable from at any particular time varies over time.


> > It turns out that it does have such a type. WindowProxy is it. I agree
> > that that makes it a special snowflake.
>
> My point is that this special snowflake is unnecessary and confusing.

Well it predates all the ES6 stuff we're talking about here by several
years, so I'd argue that the confusion doesn't stem from WindowProxy. I
also don't really agree that it's confusing. It's really simple to
explain, certainly much simpler than anything involving ES proxies and so
forth. It's one sentence in the spec, and as far as I'm aware, it doesn't
leave anything undefined.

I also disagree that what the spec says doesn't match implementations. I
think it matches implementations pretty darn closely. I mean, in
particular, it matches exactly what Travis described as IE's
implementation. (This is not an accident; matching implementations was one
of the main goals of the HTML spec, and at the time this was specced, IE
was by far the biggest UA out there.)

--
Ian Hickson               U+1047E                )\._.,--....,'``.    fL
http://ln.hixie.ch/       U+263A                /,   _.. \   _\  ;`._ ,.
Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'



--
    Cheers,
    --MarkM

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Figuring out the behavior of WindowProxy in the face of non-configurable properties

Boris Zbarsky
In reply to this post by Boris Zbarsky
On 12/4/14 5:58 AM, Boris Zbarsky wrote:
> OK.  What do we do if we discover that throwing from the defineProperty
> call with a non-configurable property descriptor is not web-compatible?

Based on a nice long conversation Yehuda and I just had, if we end up
there and really want to preserve all the current invariants we could
try a hybrid approach inspided by the Safari implementation.  To whit:

1)  Assume that we can distinguish when we're "inside" a window and when
we're "outside" it.  For example, compare the current Realm's global to
the window.

2)  When inside the window, everything works as normal: you can define a
non-configurable property on the window you're inside,
getOwnPropertyDescriptor will claim it's non-configurable, etc.  At
least while that window is current.  Once it's non-current, I haven't
tested what Safari does and am not sure what we could/should spec.

3)  When outside the window, where observing navigations is easy, we try
to apply one of the possible mitigations: throw on defineProperty that's
non-configurable or whatnot, report all props as configurable, etc.
This seems to be all kosher if we assume a membrane between inside and
outside the window, such that we're actually operating on different
objects in the two cases...

This may mitigate the compat impact depending on what compat issues we
run into.

Just wanted to get this written down while it's fresh in my mind,
Boris
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Figuring out the behavior of WindowProxy in the face of non-configurable properties

Mark S. Miller-2
Thanks. It is great to accumulate such retreats in case we need them. However, it is also good to remember that, should we run into problems, that experience will give us specific data that we might not have been able to anticipate. The least painful retreat may very well take that specific data into account.

The case of Object.prototype.toString.call(null) was an informative precedent.



On Wed, Jan 14, 2015 at 9:50 PM, Boris Zbarsky <[hidden email]> wrote:
On 12/4/14 5:58 AM, Boris Zbarsky wrote:
OK.  What do we do if we discover that throwing from the defineProperty
call with a non-configurable property descriptor is not web-compatible?

Based on a nice long conversation Yehuda and I just had, if we end up there and really want to preserve all the current invariants we could try a hybrid approach inspided by the Safari implementation.  To whit:

1)  Assume that we can distinguish when we're "inside" a window and when we're "outside" it.  For example, compare the current Realm's global to the window.

2)  When inside the window, everything works as normal: you can define a non-configurable property on the window you're inside, getOwnPropertyDescriptor will claim it's non-configurable, etc.  At least while that window is current.  Once it's non-current, I haven't tested what Safari does and am not sure what we could/should spec.

3)  When outside the window, where observing navigations is easy, we try to apply one of the possible mitigations: throw on defineProperty that's non-configurable or whatnot, report all props as configurable, etc. This seems to be all kosher if we assume a membrane between inside and outside the window, such that we're actually operating on different objects in the two cases...

This may mitigate the compat impact depending on what compat issues we run into.

Just wanted to get this written down while it's fresh in my mind,
Boris



--
    Cheers,
    --MarkM

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Figuring out the behavior of WindowProxy in the face of non-configurable properties

Ian Hickson
On Thu, 15 Jan 2015, Yehuda Katz wrote:
>
> If it's available to JavaScript consumers it must look like an object
> that obeys ES invariants to JavaScript consumers. No (new, ugh)
> exceptions.

This isn't a new exception. It predates the invariants by years.


On Wed, 14 Jan 2015, Filip Pizlo wrote:
>
> Are you saying that it’s easier to spec having the browser find all
> variables (local or otherwise) that reference some object and replace
> them with references to a different object?

Easier than what?

What I'm proposing is the following text, which has been in the spec for
years: "all operations that would be performed on it must be performed on
the Window object of the browsing context's active document instead"

It doesn't talk about finding variables or anything, though it's
isomorphic with doing that in practice, and talking about WindowProxy
objects as if they were assigned to variables whose values changed is
easier for me to describe to authors than the forwarding behaviour.


On Wed, 14 Jan 2015, Boris Zbarsky wrote:
>
> My point is that no sane implementation would possibly want to actually
> implement it that way

It's what IE does, according to Travis.


> > If there is any behaviour that is underdefined by the HTML spec's
> > current prose, please tell me, so that I can spec it.
>
> Care to ask the UA implementors who are clearly not doing anything even
> resembling your spec?  Because it might turn out they might have reasons
> for it...

I've asked you many times.


> > Well it predates all the ES6 stuff we're talking about here by several
> > years
>
> All the "stuff" involved was in ES5.  It's not new in ES6.  I've also
> pointed this out to you several times now.

I don't really care about the version number. The HTML side of this dates
back to the ES3 days.


> > it doesn't leave anything undefined.
>
> Implementations seem to disagree by their actions, sadly.

Implementations disagreeing with each other doesn't mean the spec is
undefined. It's at least as common for the implementations to just not
match the spec.


> > I also disagree that what the spec says doesn't match implementations.
>
> Uh... Have you _tried_ testing this stuff in Safari?  I have; please see
> archives for the results.  They look nothing like your spec.

It doesn't match _all_ implementations, certainly.


On Wed, 14 Jan 2015, Mark S. Miller wrote:
>
> WindowProxy is however a first class value observable by JS code

My point is that it's not. WindowProxy can literally not be observed. You
can only ever observe the Window it points to, and the only way to tell
that it changes Window is through circumstancial evidence (e.g. the
properties change).


> Neither does the magic replacement theory excuse it from violating the
> spec.

Based on when the spec prose was written, the ES spec is violating the
HTML spec here, not vice versa.


> The ES5 constraints on updating non configurable properties are eternal
> invariants.

Yes. Nothing here is violating these invariants. The invariants apply to
the Window object.


> by writing test2c, in the same spirit as test2a and test2b:
>
> (function(){"use strict";
>
> // assume "gopd" & "is" initialization runs first, so these are
> // the original functions.
> var gopd = Object.getOwnPropertyDescriptor;
> var is = Object.is;
>
> function test2c(obj, name, interleave) {
>   name = String(name);
>   var desc1 = gopd(obj, name);
>   interleave();
>   var desc2 = gopd(obj, name);
>   if (!desc1.configurable) {
>     assertFalse(desc2.configurable);
>     assertTrue(desc2.enumerable === desc2.enumerable);
>     if (gopd(desc1, 'writable') && !desc1.writable) {
>       assertFalse(desc2.writable);
>       assertTrue(is(desc1.value, desc2.value));
>     }
>   }
> }
>
> return test2c;
>
> }());
>
> In a conforming ES6 implementation (or a conforming ES5 one given the
> std "is" polyfill), it must not be possible to call test2c such that
> these asserts fail. No where do these specs say "unless interleave()
> replaces all pointers to obj to point at a different object". If it did,
> the whole notion of eternal invariants would be nonsense.
Per the HTML spec, there's two ways that WindowProxy can change. One is
session history traversal. That can never happen with JS on the stack, so
it can't violate your example above.

The other is document.open(). Behaviour around that is less interoperable,
and the current behaviour of replacing the singletons might be something
we can change, I dunno. From my understanding of what Travis described, IE
behaves exactly like the spec says, which would cause the above to assert
false. Firefox certainly does currently:

   http://software.hixie.ch/utilities/js/live-dom-viewer/?saved=3369

Chrome and Safari don't seem to replace the Window when you do
document.open(), which seems likely to be the source of bugs. I'm
surprised I haven't noticed it before. I would have assumed pages would
depend on the previous document's fiddling with Window to be removed.

--
Ian Hickson               U+1047E                )\._.,--....,'``.    fL
http://ln.hixie.ch/       U+263A                /,   _.. \   _\  ;`._ ,.
Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Figuring out the behavior of WindowProxy in the face of non-configurable properties

Boris Zbarsky
On 1/15/15 1:22 PM, Ian Hickson wrote:
> It's what IE does, according to Travis.

I'll let Travis address this.

>> Care to ask the UA implementors who are clearly not doing anything even
>> resembling your spec?  Because it might turn out they might have reasons
>> for it...
>
> I've asked you many times.

I'm not one of those implementors.  What Gecko does right now is more or
less black-box indistinguishable from your spec, modulo cross-origin
issues.  However we may be changing what we do; we'll see.

> Implementations disagreeing with each other doesn't mean the spec is
> undefined.

But it can well mean they're not willing to implement it as written.

> It doesn't match _all_ implementations, certainly.

OK, but have you bothered to find out why?

> Per the HTML spec, there's two ways that WindowProxy can change. One is
> session history traversal. That can never happen with JS on the stack

Are you sure, given showModalDialog?

-Boris
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Figuring out the behavior of WindowProxy in the face of non-configurable properties

Ian Hickson
On Thu, 15 Jan 2015, Boris Zbarsky wrote:
> >
> > It doesn't match _all_ implementations, certainly.
>
> OK, but have you bothered to find out why?

The usual reason is just that there was no spec initially, and that the
relevant implementations haven't bothered to fix it since the spec was
written.


> > Per the HTML spec, there's two ways that WindowProxy can change. One
> > is session history traversal. That can never happen with JS on the
> > stack
>
> Are you sure, given showModalDialog?

I'm assuming that showModalDialog() is dead. showModalDialog() breaks
every assumption under the sun and is generally bad news.

--
Ian Hickson               U+1047E                )\._.,--....,'``.    fL
http://ln.hixie.ch/       U+263A                /,   _.. \   _\  ;`._ ,.
Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Figuring out the behavior of WindowProxy in the face of non-configurable properties

Boris Zbarsky
In reply to this post by Mark S. Miller-2
On 12/4/14 11:49 AM, Mark S. Miller wrote:
> On Thu, Dec 4, 2014 at 2:58 AM, Boris Zbarsky <[hidden email]> wrote:
>> OK.  What do we do if we discover that throwing from the defineProperty call
>> with a non-configurable property descriptor is not web-compatible?
>
> What we always do

So just for the record, jQuery (at least all the 2.* versions I've
looked at) contains that following bits:

   Data.prototype = {
        key: function( owner ) {
...
                var descriptor = {},
...
                        // Secure it in a non-enumerable, non-writable property
                        try {
                                descriptor[ this.expando ] = { value: unlock };
                                Object.defineProperties( owner, descriptor );

                        // Support: Android < 4
                        // Fallback to a less secure definition
                        } catch ( e ) {
                                descriptor[ this.expando ] = unlock;
                                jQuery.extend( owner, descriptor );
                        }

This function is called from Data.prototype.get, which is called from
jQuery.event.add.  So the upshot is that trying to add an event listener
to the window via the jQuery API will hit this codepath.

Now the good news is that the try/catch _is_ present there, so this
doesn't immediately break sites.  But it's something to watch out for,
and we _will_ be changing the behavior of jQuery here in a way that the
jQuery developers clearly think is undesirable.

-Boris
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
123