forked from mirrors/gecko-dev
Bug 1681249 - unbreak subframes navigating ancestor frames to custom protocols, r=nika
Differential Revision: https://phabricator.services.mozilla.com/D101238
This commit is contained in:
parent
fa00168092
commit
b3aec77f8f
2 changed files with 65 additions and 0 deletions
|
|
@ -1089,6 +1089,20 @@ nsExternalHelperAppService::LoadURI(nsIURI* aURI,
|
|||
bc = parent;
|
||||
wgp = parent->Canonical()->GetCurrentWindowGlobal();
|
||||
}
|
||||
|
||||
if (!foundAccessibleFrame) {
|
||||
// See if this navigation could have come from a subframe.
|
||||
nsTArray<RefPtr<BrowsingContext>> contexts;
|
||||
aBrowsingContext->GetAllBrowsingContextsInSubtree(contexts);
|
||||
for (const auto& kid : contexts) {
|
||||
wgp = kid->Canonical()->GetCurrentWindowGlobal();
|
||||
if (wgp && aTriggeringPrincipal->Subsumes(wgp->DocumentPrincipal())) {
|
||||
foundAccessibleFrame = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundAccessibleFrame) {
|
||||
return NS_OK; // deny the load.
|
||||
}
|
||||
|
|
|
|||
|
|
@ -345,3 +345,54 @@ add_task(async function test_oop_iframe() {
|
|||
await dialogClosedPromise;
|
||||
ok(!dialog._frame.contentWindow, "The dialog should have been closed.");
|
||||
});
|
||||
|
||||
/**
|
||||
* Check that a cross-origin iframe can navigate the top frame
|
||||
* to an external protocol.
|
||||
*/
|
||||
add_task(async function xorigin_iframe_can_navigate_top() {
|
||||
let tab = await BrowserTestUtils.openNewForegroundTab(
|
||||
gBrowser,
|
||||
"https://example.com/"
|
||||
);
|
||||
|
||||
// Ensure we notice the dialog opening:
|
||||
let dialogWindowPromise = waitForProtocolAppChooserDialog(
|
||||
tab.linkedBrowser,
|
||||
true
|
||||
);
|
||||
let innerLoaded = BrowserTestUtils.browserLoaded(
|
||||
tab.linkedBrowser,
|
||||
true,
|
||||
"https://example.org/"
|
||||
);
|
||||
info("Constructing frame");
|
||||
await SpecialPowers.spawn(tab.linkedBrowser, [], function() {
|
||||
let frame = content.document.createElement("iframe");
|
||||
frame.src = "https://example.org/"; // cross-origin frame.
|
||||
content.document.body.prepend(frame);
|
||||
});
|
||||
await innerLoaded;
|
||||
|
||||
info("Navigating top bc from frame");
|
||||
let parentBC = tab.linkedBrowser.browsingContext;
|
||||
await SpecialPowers.spawn(parentBC.children[0], [], async function() {
|
||||
content.eval("window.top.location.href = 'mailto:example@example.com';");
|
||||
});
|
||||
|
||||
let dialog = await dialogWindowPromise;
|
||||
|
||||
is(
|
||||
dialog._frame.contentDocument.location.href,
|
||||
CONTENT_HANDLING_URL,
|
||||
"Dialog opens as expected for navigating the top frame from an x-origin frame."
|
||||
);
|
||||
// Close the dialog:
|
||||
let dialogClosedPromise = waitForProtocolAppChooserDialog(
|
||||
tab.linkedBrowser,
|
||||
false
|
||||
);
|
||||
dialog.close();
|
||||
await dialogClosedPromise;
|
||||
gBrowser.removeTab(tab);
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue