Auto merge of #24664 - gterzian:fix_port_transfer, r=jdm

Fix loophole in messageport transfer

<!-- Please describe your changes on the following line: -->

---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `___` with appropriate data: -->
- [ ] `./mach build -d` does not report any errors
- [ ] `./mach test-tidy` does not report any errors
- [ ] These changes fix #24600 (GitHub issue number if applicable)

<!-- Either: -->
- [ ] There are tests for these changes OR
- [ ] These changes do not require tests because ___

<!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.-->

<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->
This commit is contained in:
bors-servo 2019-11-18 11:35:25 -05:00 committed by GitHub
commit 0d2c2045cc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 468 additions and 52 deletions

View file

@ -11296,6 +11296,32 @@
{}
]
],
"mozilla/Channel_postMessage_with_second_transfer_in_timeout.window.js": [
[
"mozilla/Channel_postMessage_with_second_transfer_in_timeout.window.html",
{
"script_metadata": [
[
"script",
"/common/get-host-info.sub.js"
]
]
}
]
],
"mozilla/Channel_postMessage_with_second_transfer_in_timeout_with_delay.window.js": [
[
"mozilla/Channel_postMessage_with_second_transfer_in_timeout_with_delay.window.html",
{
"script_metadata": [
[
"script",
"/common/get-host-info.sub.js"
]
]
}
]
],
"mozilla/DOMParser.html": [
[
"mozilla/DOMParser.html",
@ -18432,6 +18458,14 @@
"276791c4348ada7e1da71041f2ccd383305e209c",
"support"
],
"mozilla/Channel_postMessage_with_second_transfer_in_timeout.window.js": [
"4ee3f64beb095963f06fc53c1d53dad2244109f9",
"testharness"
],
"mozilla/Channel_postMessage_with_second_transfer_in_timeout_with_delay.window.js": [
"939995678895c07047709f6e265d0f6b7b705eb5",
"testharness"
],
"mozilla/DOMParser.html": [
"f386a3e0191af2c70dcb05790ce7db15dd5ccbf1",
"testharness"

View file

@ -0,0 +1,33 @@
// META: script=/common/get-host-info.sub.js
async_test(function(t) {
var channel1 = new MessageChannel();
var channel2 = new MessageChannel();
var host = get_host_info();
let iframe = document.createElement('iframe');
iframe.src = host.HTTP_NOTSAMESITE_ORIGIN + "/webmessaging/support/ChildWindowPostMessage.htm";
document.body.appendChild(iframe);
var TARGET = document.querySelector("iframe").contentWindow;
iframe.onload = t.step_func(function() {
// Send a message, expecting it to be received in the iframe.
channel1.port2.postMessage(1)
// First, transfer the port into the same realm.
channel2.port2.postMessage(0, [channel1.port1]);
channel2.port1.onmessage = t.step_func(function (evt) {
assert_equals(Number(evt.data), 0);
t.step_timeout(function () {
// Transfer the port to the iframe.
TARGET.postMessage("ports", "*", evt.ports);
}, 0);
});
channel1.port2.onmessage = t.step_func(function (evt) {
assert_equals(Number(evt.data), 1);
t.done();
});
});
}, `A port transferred outside of a onmessage handler does not lose messages along the way.`);

View file

@ -0,0 +1,43 @@
// META: script=/common/get-host-info.sub.js
async_test(function(t) {
var channel1 = new MessageChannel();
var channel2 = new MessageChannel();
var host = get_host_info();
let iframe = document.createElement('iframe');
iframe.src = host.HTTP_NOTSAMESITE_ORIGIN + "/webmessaging/support/ChildWindowPostMessage.htm";
document.body.appendChild(iframe);
var TARGET = document.querySelector("iframe").contentWindow;
iframe.onload = t.step_func(function() {
// Send a message, expecting it to be received in the iframe.
channel1.port2.postMessage(1)
// First, transfer the port into the same realm.
channel2.port2.postMessage(0, [channel1.port1]);
channel2.port1.onmessage = t.step_func(function (evt) {
assert_equals(Number(evt.data), 0);
t.step_timeout(function () {
// Transfer the port to the iframe.
TARGET.postMessage("ports", "*", evt.ports);
// Keep the event-loop busy for one second,
// which will result in the iframe
// starting the "complete port transfer" flow,
// before the window global could finish it's own.
var request = new XMLHttpRequest();
request.open('GET', 'blank.html?pipe=trickle(d1)', false);
request.send(null);
}, 0);
});
channel1.port2.onmessage = t.step_func(function (evt) {
assert_equals(Number(evt.data), 1);
t.done();
});
});
}, `A port transferred outside of a onmessage handler,
followed by a delay in returning the buffer caused by blocking the event-loop,
does not lose messages along the way.`);