Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Named properties object / named property visibility algorithm with property on Window.prototype #607

Open
Ms2ger opened this issue Jan 11, 2019 · 4 comments

Comments

@Ms2ger
Copy link
Member

Ms2ger commented Jan 11, 2019

When there's a property on Window.prototype, the named property visibility algorithm called on window will return false in step 5.1, when prototype is Window.prototype. This implies that [[GetOwnProperty]] on the named properties object will fall back to calling OrdinaryGetOwnProperty(O, P), which returns undefined.

However, the browsers I tested consistently return the result of the named getter.

Consider the following code:

<!DOCTYPE html>
<span id=foo></span>
...<script>
var wp = window.__proto__;
var npo = window.__proto__.__proto__;
wp.foo = 7;
w(wp)
w(npo)
w(window.foo)
w(wp.foo)
>>>> w(npo.foo);

w("------")

var ep = npo.__proto__;
ep.bar = 7;
w(ep)
w(window.bar)
w(wp.bar)
w(npo.bar);
w(ep.bar);
</script>

This logs the same in Firefox, Chrome dev and Epiphany:

log: object "[object WindowPrototype]" (4 props: foo=7, addEventListener=function addEventListener() {\n    [native code]\n}, removeEventListener=function removeEventListener() {\n    [native code]\n}, dispatchEvent=function dispatchEvent() {\n    [native code]\n})
log: object "[object WindowProperties]" (3 props: addEventListener=function addEventListener() {\n    [native code]\n}, removeEventListener=function removeEventListener() {\n    [native code]\n}, dispatchEvent=function dispatchEvent() {\n    [native code]\n})
log: 7
log: 7
>>>> log: object "[object HTMLSpanElement]" (242 props: click=function click() {\n    [native code]\n}, focus=function focus() {\n    [native code]\n}, blur=function blur() {\n    [native code]\n}, title=""...)
log: ------

(Edit: ignore the results below; Chrome is doing something weirder and I didn't notice because I failed to actually include the span.)

log: object "[object EventTargetPrototype]" (4 props: addEventListener=function addEventListener() {\n    [native code]\n}, removeEventListener=function removeEventListener() {\n    [native code]\n}, dispatchEvent=function dispatchEvent() {\n    [native code]\n}, bar=7)
log: 7
log: 7
log: 7
log: 7
@annevk
Copy link
Member

annevk commented Jan 11, 2019

Well yes, but the operations you're using here invoke [[Get]], no? And [[Get]] invokes OrdinaryGet which goes over a chain as browsers do.

@domenic
Copy link
Member

domenic commented Jan 11, 2019

Yeah, to invoke [[GetOwnProperty]] you'd need to use Object.getOwnPropertyDescriptor(window, "foo") or similar.

@bzbarsky
Copy link
Collaborator

bzbarsky commented Jan 11, 2019

Testcase that actually exercises [[GetOwnProperty]]: http://software.hixie.ch/utilities/js/live-dom-viewer/?saved=6506

Looks to me like Safari and Firefox are following the spec here. Chrome is not: it returns a property descriptor from npo for property name "bar" pointing to one of the <span>s, but somehow a [[Get]] on the window returns 7, skipping over that property that it claims exists. So the observable effect of [[Get]] on the window is the same, which is what largely matters for web compat, but Chrome is using some sort of weird magic to implement it.

@bzbarsky
Copy link
Collaborator

Ah, @Ms2ger clarified that he's talking about this case, specifically:

  1. There is an element with id "foo".
  2. There is a property on Window.prototype with name "foo".
  3. You do a property lookup for "foo", via [[Get]] or [[GetOwnProperty]] on the named properties object.

Per spec, those lookups should not find the element, because https://heycam.github.io/webidl/#named-properties-object-getownproperty step 2 does the visibility check on the window, not on the named properties object itself, finds the property on Window.prototype, and then says the named property object has no property named "foo".

As @Ms2ger points out, no browsers do that. What's really at stake here is making sure that the named properties object doesn't shadow anything higher on the prototype chain, so that's what Firefox checks: that there is no such property on the prototype chain of the named properties object. Window.prototype is not on said proto chain, but also can't be shadowed by the named properties object, so doesn't have to be checked.

I suspect we could take out step 2 there and remove the check for a "named properties object" in https://heycam.github.io/webidl/#dfn-named-property-visibility step 5.1 and things would be just fine web compat wise, and the behavior simpler/saner.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging a pull request may close this issue.

4 participants