- From: Boris Zbarsky <bzbarsky@MIT.EDU>
- Date: Thu, 08 Aug 2013 15:38:24 -0400
- To: Ian Hickson <ian@hixie.ch>
- Cc: whatwg@lists.whatwg.org
On 8/8/13 2:48 PM, Ian Hickson wrote: >> The current spec calls for the Window to be a proxy-like object, because >> that's the only way to implement the spec's indexed getter behavior. > > I don't understand what you mean. What's different about Window's indexed > getter behaviour than the indexed getter behaviours of all the other > interfaces in HTML that have indexed getters? Absolutely nothing. All the other indexed getter behaviors in HTML require proxy-like behavior. But none of the rest of them are the global object, so they can just be proxies and do their weird proxy things (again, in ES6 terms), and it's all ok. >> "var" needs to be able to define non-configurable properties. Proxies >> don't necessarily offer useful guarantees about being able to define >> such properties on them, and in particular the behavior for index/named >> getters in WebIDL precludes definition of non-configurable properties of >> the corresponding kind on the relevant object. > > I don't understand what this means, sorry. Hmm. Which part is unclear? > If WebIDL makes it hard for an object that has indexed and named getters > to also be a [Global] object, then we should fix WebIDL, since 33% of the > [Global] objects, and nearly 100% of the actual [Global] objects in the > wild, have indexed and named getters. This is not a problem with WebIDL. This is a problem with the fact that indexed and named getters as implemented in modern browsers effectively violate ES language invariants that the global is not allowed to violate. Now the good thing is that we defined things in WebIDL so that this is ok: the named getters on the global are NOT on the global itself, but on the NamedPropertiesObject on its prototype chain (and the difference is readily observable; try "var foo = 5; alert(foo);" in a page that has <iframe name="foo"> and note that you get 5, which you would not if the named getter were on the Window directly). And the indexed getter on Window, as I said, is black-box indistinguishable from living on the WindowProxy, because you can't use indices as barewords. So the upshot is that a UA can just put them there and not have conflicts with the ES spec. But, once again, if that's what UAs end up having to do anyway, we may as well spec it that way. >> I'm not sure what you mean. The "mapping" that needs to happen is "how >> do I have a global that's not a magic proxy while being black-box >> compatible with the spec?" > > The Window object is just a regular object as far as I can tell. It has no > magical proxiness. The indexed getter behavior is "magical proxiness" as implemented in UAs and specced in WebIDL. Again, in ES6 terms. And we've tried to find other ways to define it; they all suck even more. > That's only WindowProxy, which isn't the global. I think we might be using two different definitions of "proxy". I am using "proxy" to indicate objects for which a normal, non-Proxy, user-created object in JS would not be able to emulate their behavior. Objects like that are why ES introduced Proxy objects, which are able to have a much wider range of behaviors than normal objects, because they can hook into various operations on a much lower level (specifically, they can more or less directly implement the MOP). >> Because getOwnPropertyNames should return the own properties of the >> object, but doing that on a WindowProxy for a cross-origin window should >> not in fact return the Window's own properties. > > Yes, it should. At least, IMHO. Er... That's a cross-site information leak. While some browsers apparently do in fact have this leak, the web does not require it, I don't think we should spec it, and Gecko certainly has no plans to add it. > WindowProxy should be _completely indistinguishable_ from the Window it > currently points to, except for the way it can be distinguished when what > it points to changes. OK, so in this view there are multiple (one per origin, roughly) Window objects in JS all representing the same underlying browser object? I don't understand how this can work with document.domain, where things that used to not be same-origin suddenly become same-origin: in that situation two different origins become the same origin and the fact that they have different Window objects for the same current window ends up observable. I feel like I must be missing something about the model you're working with here. >> Or another similar issue: getting a property descriptor from a >> WindowProxy (for a same-origin window) should probably never claim to >> have a non-configurable property, because on navigation the property >> will in fact disappear and non-configurable properties are not allowed >> to do that in ES. > > IMHO, yes, it should. That's not allowed in ES. Do see the thread I linked to. >> See >> http://lists.w3.org/Archives/Public/public-script-coord/2012OctDec/0386.html >> and the threads it references. But of course Window is required to be >> able to have non-configurable properties (see "var"). So WindowProxy >> can't just forward [[GetOwnProperty]] on to the Window. > > I think you're making this more complicated than it need be. > > Conceptually, it's just that the pointers to Window objects get redirected > to point to a different Window object when the browsing context navigates. Let me try to make this clearer. If an object (in this case a WindowProxy, since that's what the script is working with) ever claims that it has a non-configurable property for some property name, ES requires that it _always_ do that from that point on. This is a fundamental invariant that other parts of ES are built on, and security libraries (caja and the like) plan to make use of this invariant. > It's as if script had gone through every variable that points to the first > Window object and set the variable to point to the new Window object. I understand your mental model for this part; I'm just telling you that it contradicts the ES spec and we need to reconcile the contradiction somehow. > Every single MOP primitive for WindowProxy should just transparently proxy > to the current underlying Window MOP primitive. See above. -Boris
Received on Thursday, 8 August 2013 19:38:51 UTC