mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-21 09:15:35 +00:00
Bug 1590526 - Temporarily allow node adoption across different docGroups for the content/content case r=smaug,zombie
As web extensions rely on this node adoption between content to content documents, we want to continue allowing this capability to work for now. Differential Revision: https://phabricator.services.mozilla.com/D50348 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
78e89d3ba7
commit
a269703b7c
@ -295,3 +295,5 @@ skip-if = os == 'mac' # Fails when windows are randomly opened in fullscreen mod
|
||||
skip-if = (verify && (os == 'mac'))
|
||||
tags = fullscreen
|
||||
[browser_ext_contentscript_animate.js]
|
||||
[browser_ext_contentscript_cross_docGroup_adoption.js]
|
||||
[browser_ext_contentscript_cross_docGroup_adoption_xhr.js]
|
||||
|
@ -0,0 +1,58 @@
|
||||
/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set sts=2 sw=2 et tw=80: */
|
||||
"use strict";
|
||||
|
||||
add_task(async function test_cross_docGroup_adoption() {
|
||||
let tab = await BrowserTestUtils.openNewForegroundTab(
|
||||
gBrowser,
|
||||
"http://example.com/"
|
||||
);
|
||||
|
||||
let extension = ExtensionTestUtils.loadExtension({
|
||||
manifest: {
|
||||
content_scripts: [
|
||||
{
|
||||
matches: ["http://example.com/"],
|
||||
js: ["content-script.js"],
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
files: {
|
||||
"current.html": "<html>data</html>",
|
||||
"content-script.js": function() {
|
||||
let iframe = document.createElement("iframe");
|
||||
iframe.src = browser.extension.getURL("current.html");
|
||||
document.body.appendChild(iframe);
|
||||
|
||||
iframe.addEventListener(
|
||||
"load",
|
||||
() => {
|
||||
let parser = new DOMParser();
|
||||
let bold = parser.parseFromString(
|
||||
"<b>NodeAdopted</b>",
|
||||
"text/html"
|
||||
);
|
||||
let doc = iframe.contentDocument;
|
||||
|
||||
let node = document.adoptNode(bold.documentElement);
|
||||
doc.replaceChild(node, doc.documentElement);
|
||||
|
||||
const expected =
|
||||
"<html><head></head><body><b>NodeAdopted</b></body></html>";
|
||||
browser.test.assertEq(expected, doc.documentElement.outerHTML);
|
||||
|
||||
browser.test.notifyPass("nodeAdopted");
|
||||
},
|
||||
{ once: true }
|
||||
);
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
await extension.startup();
|
||||
await extension.awaitFinish("nodeAdopted");
|
||||
await extension.unload();
|
||||
|
||||
BrowserTestUtils.removeTab(tab);
|
||||
});
|
@ -0,0 +1,51 @@
|
||||
/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set sts=2 sw=2 et tw=80: */
|
||||
"use strict";
|
||||
|
||||
add_task(async function test_cross_docGroup_adoption() {
|
||||
let tab = await BrowserTestUtils.openNewForegroundTab(
|
||||
gBrowser,
|
||||
"http://example.com/"
|
||||
);
|
||||
|
||||
let extension = ExtensionTestUtils.loadExtension({
|
||||
manifest: {
|
||||
content_scripts: [
|
||||
{
|
||||
matches: ["http://example.com/"],
|
||||
js: ["content-script.js"],
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
files: {
|
||||
"blank.html": "<html>data</html>",
|
||||
"content-script.js": function() {
|
||||
let xhr = new XMLHttpRequest();
|
||||
xhr.responseType = "document";
|
||||
xhr.open("GET", browser.extension.getURL("blank.html"));
|
||||
|
||||
xhr.onload = function() {
|
||||
let doc = xhr.response;
|
||||
try {
|
||||
let node = doc.body.cloneNode(true);
|
||||
document.body.appendChild(node);
|
||||
browser.test.notifyPass("nodeAdopted");
|
||||
} catch (SecurityError) {
|
||||
browser.test.assertTrue(
|
||||
false,
|
||||
"The above node adoption should not fail"
|
||||
);
|
||||
}
|
||||
};
|
||||
xhr.send();
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
await extension.startup();
|
||||
await extension.awaitFinish("nodeAdopted");
|
||||
await extension.unload();
|
||||
|
||||
BrowserTestUtils.removeTab(tab);
|
||||
});
|
@ -13,6 +13,7 @@
|
||||
#include "mozilla/dom/Document.h"
|
||||
#include "js/TypeDecls.h"
|
||||
#include "nsCOMArray.h"
|
||||
#include "nsContentUtils.h"
|
||||
|
||||
struct CharacterDataChangeInfo;
|
||||
template <class E>
|
||||
@ -206,15 +207,22 @@ class nsNodeUtils {
|
||||
nsCOMArray<nsINode>& aNodesWithProperties,
|
||||
mozilla::ErrorResult& aError) {
|
||||
if (aNode && aNewNodeInfoManager) {
|
||||
mozilla::dom::Document* newDoc = aNewNodeInfoManager->GetDocument();
|
||||
mozilla::dom::Document* oldDoc = aNode->OwnerDoc();
|
||||
if (newDoc && oldDoc &&
|
||||
(oldDoc->GetDocGroup() != newDoc->GetDocGroup())) {
|
||||
MOZ_ASSERT(false, "Cross docGroup adoption is not allowed");
|
||||
mozilla::dom::Document* afterAdoptDoc =
|
||||
aNewNodeInfoManager->GetDocument();
|
||||
mozilla::dom::Document* beforeAdoptDoc = aNode->OwnerDoc();
|
||||
|
||||
if (afterAdoptDoc && beforeAdoptDoc &&
|
||||
(afterAdoptDoc->GetDocGroup() != beforeAdoptDoc->GetDocGroup())) {
|
||||
// This is a temporary solution for Bug 1590526 to only limit
|
||||
// the restriction to chrome level documents because web extensions
|
||||
// rely on content to content node adoption.
|
||||
if (nsContentUtils::IsChromeDoc(afterAdoptDoc) ||
|
||||
nsContentUtils::IsChromeDoc(beforeAdoptDoc)) {
|
||||
aError.Throw(NS_ERROR_DOM_SECURITY_ERR);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Just need to store the return value of CloneAndAdopt in a
|
||||
// temporary nsCOMPtr to make sure we release it.
|
||||
|
@ -6,6 +6,7 @@ skip-if = os == 'android'
|
||||
support-files = test_offsets.css test_offsets.js
|
||||
skip-if = (os == "mac" && debug) #leaks Bug 1571583
|
||||
[test_spacetopagedown.html]
|
||||
[test_nodeAdoption_chrome_boundary.xul]
|
||||
[test_focusrings.xul]
|
||||
support-files = file_focusrings.html
|
||||
skip-if = toolkit == 'android' #TIMED_OUT
|
||||
|
@ -0,0 +1,28 @@
|
||||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
|
||||
|
||||
<window title="Cross chrome and content node adoption test"
|
||||
onload="setTimeout(runTest, 0);"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
|
||||
<script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
|
||||
<browser xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" id="content" type="content" src="about:blank"/>
|
||||
|
||||
<script>
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
function runTest()
|
||||
{
|
||||
let browserElement = document.getElementById("content");
|
||||
try {
|
||||
document.adoptNode(browserElement.contentDocument.documentElement);
|
||||
SimpleTest.ok(false, "Cross chrome and content node adoption should fail");
|
||||
} catch (SecurityError) {
|
||||
SimpleTest.ok(true, "Cross chrome and content node adoption fails as expected");
|
||||
}
|
||||
SimpleTest.finish();
|
||||
}
|
||||
</script>
|
||||
</window>
|
||||
|
Loading…
Reference in New Issue
Block a user