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

Simplifying incument realm definition to match Blink? #2535

Closed
domenic opened this issue Apr 14, 2017 · 9 comments
Closed

Simplifying incument realm definition to match Blink? #2535

domenic opened this issue Apr 14, 2017 · 9 comments

Comments

@domenic
Copy link
Member

domenic commented Apr 14, 2017

Blink, in particular @yuki3, is thinking about implementing the incumbent concept in Q2. However, I wanted to check in first to see if maybe we should change the spec to use what Blink currently does, in case it is simpler. /cc @bzbarsky @bholley
There

Some discussion has already taken place in the margins of a Blink quarter-planning doc, but let's move it here. There @yuki3 says:

What Blink is currently doing for Incumbent realm is:

// Blink returns a function object created in the Current realm.
f = iframe.contentWindow.location.replace;

// Use |f|'s creation realm as the Incumbent realm.
f('url');

This is a totally different approach from the spec, but works the same for most cases, just because the calling realm of |f| is luckily the Current realm for most cases.

I believe this "function object created in the current realm" business matches the spec already, as of last year's work on cross-origin properties. So the question is about using f's realm (i.e., the current realm at the time the algorithm is running) vs. the incumbent realm.

Going through the examples in the spec in the linked section, as far as I can tell this means:

  • Blink uses the current Realm for the MessageChannel example
  • Blink uses window for the postMessage.bind example, via a much simpler path than the spec.
  • Blink uses a's environment settings object for the "final even more convoluted example", via a much simpler path than the spec.

I'm not sure what other test cases we might want to involve, but this does seem pretty nice and simple. @bzbarsky, can you think of any downsides to switching to Blink's version? Concretely, I guess that would mean replacing all references to "incumbent settings object" with "current settings object"---which is kind of where we were heading anyway, via #1430.

(This seems too easy, so I'm probably missing something...)

There's also at least some chance (untested) that Blink and WebKit still match, which would imply a shorter path to interop via aligning with Blink.

@domenic
Copy link
Member Author

domenic commented Apr 14, 2017

Oh, right. Re-reading #1542 this only works because Chrome has the not-per-spec implementation of creating new function wrappers for every cross-window method access, not just cross-origin ones. Since I'm pretty sure we don't want to copy that, this issue is probably moot, as we'll still need a relatively-complicated incumbent definition to take care of at least postMessage (again see #1542).

I'll leave this open in case @bzbarsky and @bholley want to comment on the prospect of creating function wrappers for every cross-window method access, but I'm now less hopeful.

@bzbarsky
Copy link
Contributor

Does Chrome create new function wrappers for same-origin cross-window access for all properties, or just some properties?

@yuki3
Copy link
Contributor

yuki3 commented Apr 19, 2017

Chrome currently creates new function wrappers for cross-origin accessible DOM operations.
Cross-origin accessible DOM attributes are handled differently.

@annevk
Copy link
Member

annevk commented Apr 19, 2017

@yuki3 I think it would help if you could clarify that a bit more. In particular, neither DOM operation nor DOM attribute (IDL attribute, therefore JavaScript getter/setter?) is a defined term. Also, do you mean that it creates wrappers for those even when accessed same-origin?

@yuki3
Copy link
Contributor

yuki3 commented Apr 19, 2017

Sorry, I meant that Chrome creates new function wrappers for same-origin cross-window access for cross-origin accessible IDL operations. When you access a cross-origin accessible IDL operation, Chrome returns a function wrapper created in the Current realm. Chrome creates a function wrapper per realm and re-uses it in the same realm.

@bzbarsky
Copy link
Contributor

So in other words, otherWindow.postMessage and otherWindow.alert have different behavior in Chrome, in the case when otherWindow is same-origin.

@domenic
Copy link
Member Author

domenic commented Apr 19, 2017

Yes, concretely in that otherWindow.postMessage instanceof window.Function whereas otherWindow.alert instanceof otherWindow.Function.

What do you think of that? Horrible hack? Innovative solution? My assumption is that you'd prefer to stay the course on tracking and defining incumbent, but I realized we never discussed this idea seriously, besides calling it a Chrome bug.

@bzbarsky
Copy link
Contributor

So... Some testing shows that the above description of Chrome's behavior is at best incomplete. For example, if either page assigns to postMessage on the window in question, after that point they see the same value.

So concretely, if I have this page:

<iframe srcdoc='
    <script>
      var postMessage = postMessage;
      addEventListener("message", function(e) {
        console.log(e.source == this);
      });
    </script>
    '></iframe>
<script>
  onload = function() {
    frames[0].postMessage(null, "*");
  }
</script>

that logs true but if the var postMessage = postMessage; line is commented out it logs false.

Same thing if the subframe just does Object.defineProperty(window, "postMessage", { configurable: false });. After that point anyone that's same-origin and posting messages to it will end up with the "wrong" source in the MessageEvent.

The good news is that at least this means the MOP invariants are not violated. The bad news is that this behavior is rather surprising...

@domenic
Copy link
Member Author

domenic commented Jun 14, 2017

Let's not do this; closing.

@domenic domenic closed this as completed Jun 14, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

4 participants