Commit b205720e authored by danakj's avatar danakj Committed by Commit Bot

Prevent TestRunnerBindings from acting when it outlives the frame.

The TestRunnerBindings::TooltipText() method was changed to use the
main frame instead of the bound frame, to avoid a crash, but that would
give an incorrect result in an iframe and crash in an OOP iframe.

We move it back to using the bound frame, but acknowledge new
understanding given to us by the blessed clusterfuzz bots. In the test
it binds an iframe's window, and thus its window.testRunner, objects
to a variable in the parent frame, and then detaches the child. This
means the TestRunnerBindings is kept alive, but the RenderFrame its
attached to goes away.

To handle this case, we introduce a RenderFrameObserver for the
TestRunnerBindings. When the RenderFrame is destroyed, the
TestRunnerBindings sets |invalid_|, invalidates its weak pointers, and
stops doing anything ever again. It should not use any of its state
from that point forward as it is a detached zombie of an object.

With this change, the WeakPtr to TestRunner is now understood, but
not needed as it is redundant with |invalid_|, so we remove that.

R=avi@chromium.org

Bug: 1084717, 866140, 1069111
Change-Id: I6038fd83162d099f220dab632e051fb08ccd8af7
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2210670
Commit-Queue: danakj <danakj@chromium.org>
Reviewed-by: default avatarAvi Drissman <avi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#771133}
parent e90bd0c7
......@@ -14,7 +14,7 @@ function test() {
testRunner.waitUntilDone();
var ifr = document.querySelector("iframe");
ifr.contentWindow.test(ifr.offsetLeft, ifr.offsetTop);
ifr.contentWindow.test();
}
function finishUp() {
......
<html>
<script>
function dragElement(srcElement, gx, gy, deltaX, deltaY) {
var x = gx + srcElement.offsetLeft + 7;
var y = gy + srcElement.offsetTop + 7;
function dragElement(srcElement, deltaX, deltaY) {
var x = srcElement.offsetLeft;
var y = srcElement.offsetTop;
eventSender.mouseMoveTo(x, y);
eventSender.mouseDown();
eventSender.leapForward(100);
......@@ -12,9 +12,14 @@ function dragElement(srcElement, gx, gy, deltaX, deltaY) {
window.ondragend = function() { window.parent.finishUp(); };
function test(x, y) {
dragElement(document.getElementById('anchor'), x, y, 50, 50);
testRunner.notifyDone();
function test() {
// Stash the parent so we can use it after |window| is gone.
var w = window.parent;
// This does a drag and drop, which will delete this frame when the
// drag ends, via the ondragend handler above.
dragElement(document.getElementById('anchor'), 50, 50);
// End the test through the parent.
w.testRunner.notifyDone();
}
</script>
<body>
......
......@@ -6,6 +6,14 @@ if (window.testRunner) {
}
var iframe = document.getElementById("i");
iframe.src = "javascript:\"<script>var w = window; parent.document.body.innerHTML = 'PASS if no crash.'; if (w.testRunner) testRunner.notifyDone();</scri" + "pt>\"";
iframe.src = "javascript:" +
"\"<script>" +
// Stash the parent so we can use it after |window| is gone.
" var w = window.parent;" +
// This detaches the |iframe|, which makes |window| null.
" window.parent.document.body.innerHTML = 'PASS if no crash.';" +
// End the test through the parent.
" w.testRunner.notifyDone();" +
"</" + "script>\"";
document.body.appendChild(iframe)
</script>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment