mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Fix for bug 548463 (Disallow adopting node into a different document from adoptNode). r=sicking.
--HG-- extra : rebase_source : 5c00c3b6c65491997984d216f5c61052ccc0a77b
This commit is contained in:
parent
a1e02e2b1a
commit
6469f57d89
@ -6056,6 +6056,10 @@ nsDocument::AdoptNode(nsIDOMNode *aAdoptedNode, nsIDOMNode **aResult)
|
||||
PR_FALSE);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (adoptedNode->GetOwnerDoc() != this) {
|
||||
return NS_ERROR_DOM_WRONG_DOCUMENT_ERR;
|
||||
}
|
||||
|
||||
return CallQueryInterface(adoptedNode, aResult);
|
||||
}
|
||||
|
||||
|
@ -3766,13 +3766,15 @@ nsGenericElement::doReplaceOrInsertBefore(PRBool aReplace,
|
||||
return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
|
||||
}
|
||||
|
||||
nsIDocument *doc = container->GetOwnerDoc();
|
||||
|
||||
// DocumentType nodes are the only nodes that can have a null
|
||||
// ownerDocument according to the DOM spec, and we need to allow
|
||||
// inserting them w/o calling AdoptNode().
|
||||
if (!container->HasSameOwnerDoc(newContent) &&
|
||||
(nodeType != nsIDOMNode::DOCUMENT_TYPE_NODE ||
|
||||
newContent->GetOwnerDoc())) {
|
||||
nsCOMPtr<nsIDOM3Document> domDoc = do_QueryInterface(aDocument);
|
||||
nsCOMPtr<nsIDOM3Document> domDoc = do_QueryInterface(doc);
|
||||
|
||||
if (domDoc) {
|
||||
nsCOMPtr<nsIDOMNode> adoptedKid;
|
||||
@ -3780,6 +3782,9 @@ nsGenericElement::doReplaceOrInsertBefore(PRBool aReplace,
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
NS_ASSERTION(adoptedKid == aNewChild, "Uh, adopt node changed nodes?");
|
||||
NS_ASSERTION(container->HasSameOwnerDoc(newContent) &&
|
||||
doc == container->GetOwnerDoc(),
|
||||
"ownerDocument changed again after adopting!");
|
||||
}
|
||||
}
|
||||
|
||||
@ -3854,12 +3859,16 @@ nsGenericElement::doReplaceOrInsertBefore(PRBool aReplace,
|
||||
mutated = mutated || guard.Mutated(1);
|
||||
}
|
||||
|
||||
// If we've had any unexpeted mutations so far we need to recheck that
|
||||
// If we've had any unexpected mutations so far we need to recheck that
|
||||
// the child can still be inserted.
|
||||
if (mutated) {
|
||||
for (i = 0; i < count; ++i) {
|
||||
// Get the n:th child from the array.
|
||||
nsIContent* childContent = fragChildren[i];
|
||||
if (!container->HasSameOwnerDoc(childContent) ||
|
||||
doc != childContent->GetOwnerDoc()) {
|
||||
return NS_ERROR_DOM_WRONG_DOCUMENT_ERR;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMNode> tmpNode = do_QueryInterface(childContent);
|
||||
PRUint16 tmpType = 0;
|
||||
@ -3911,7 +3920,6 @@ nsGenericElement::doReplaceOrInsertBefore(PRBool aReplace,
|
||||
}
|
||||
|
||||
// Fire mutation events. Optimize for the case when there are no listeners
|
||||
nsIDocument* doc = container->GetOwnerDoc();
|
||||
nsPIDOMWindow* window = nsnull;
|
||||
if (doc && (window = doc->GetInnerWindow()) &&
|
||||
window->HasMutationListeners(NS_EVENT_BITS_MUTATION_NODEINSERTED)) {
|
||||
@ -3969,6 +3977,10 @@ nsGenericElement::doReplaceOrInsertBefore(PRBool aReplace,
|
||||
}
|
||||
|
||||
if (guard.Mutated(1)) {
|
||||
if (doc != newContent->GetOwnerDoc()) {
|
||||
return NS_ERROR_DOM_WRONG_DOCUMENT_ERR;
|
||||
}
|
||||
|
||||
insPos = refContent ? container->IndexOf(refContent) :
|
||||
container->GetChildCount();
|
||||
if (insPos < 0) {
|
||||
|
@ -41,16 +41,14 @@
|
||||
#include "nsDOMAttributeMap.h"
|
||||
#include "nsIDOMNode.h"
|
||||
#include "nsIMutationObserver.h"
|
||||
#include "nsINode.h"
|
||||
|
||||
struct JSContext;
|
||||
struct JSObject;
|
||||
class nsINode;
|
||||
class nsNodeInfoManager;
|
||||
class nsIVariant;
|
||||
class nsIDOMUserDataHandler;
|
||||
template<class E> class nsCOMArray;
|
||||
class nsCycleCollectionTraversalCallback;
|
||||
struct CharacterDataChangeInfo;
|
||||
|
||||
class nsNodeUtils
|
||||
{
|
||||
@ -193,8 +191,14 @@ public:
|
||||
JSObject *aNewScope,
|
||||
nsCOMArray<nsINode> &aNodesWithProperties)
|
||||
{
|
||||
return CloneAndAdopt(aNode, PR_FALSE, PR_TRUE, aNewNodeInfoManager, aCx,
|
||||
aOldScope, aNewScope, aNodesWithProperties, nsnull);
|
||||
nsresult rv = CloneAndAdopt(aNode, PR_FALSE, PR_TRUE, aNewNodeInfoManager,
|
||||
aCx, aOldScope, aNewScope, aNodesWithProperties,
|
||||
nsnull);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsMutationGuard::DidMutate();
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -358,6 +358,7 @@ _TEST_FILES = test_bug5141.html \
|
||||
file_CSP_evalscript_main.js \
|
||||
test_bug540854.html \
|
||||
bug540854.sjs \
|
||||
test_bug548463.html \
|
||||
$(NULL)
|
||||
|
||||
# This test fails on the Mac for some reason
|
||||
|
84
content/base/test/test_bug548463.html
Normal file
84
content/base/test/test_bug548463.html
Normal file
@ -0,0 +1,84 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=548463
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 548463</title>
|
||||
<script type="application/javascript" src="/MochiKit/packed.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=548463">Mozilla Bug 548463</a>
|
||||
<p id="display"></p>
|
||||
<iframe id="otherDoc"></iframe>
|
||||
<div id="content" style="display: none">
|
||||
<p id="elem1"></p>
|
||||
<p id="elem2"></p>
|
||||
</div>
|
||||
<div id="otherContent" style="display: none">
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 548463 **/
|
||||
|
||||
var otherDoc = document.getElementById("otherDoc").contentDocument;
|
||||
var content = document.getElementById("content");
|
||||
var elem1 = document.getElementById("elem1");
|
||||
var elem2 = document.getElementById("elem2");
|
||||
|
||||
function testAdoptFromDOMNodeRemoved(nodeToAppend, nodeRemoved, nodeToAdopt)
|
||||
{
|
||||
function reparent(event)
|
||||
{
|
||||
if (event.target == nodeRemoved) {
|
||||
nodeRemoved.removeEventListener("DOMNodeRemoved", arguments.callee, false);
|
||||
otherDoc.adoptNode(nodeToAdopt);
|
||||
}
|
||||
}
|
||||
nodeRemoved.addEventListener("DOMNodeRemoved", reparent, false);
|
||||
|
||||
var thrown = false;
|
||||
try {
|
||||
document.getElementById("otherContent").appendChild(nodeToAppend);
|
||||
}
|
||||
catch (e) {
|
||||
thrown = true;
|
||||
}
|
||||
|
||||
ok(thrown, "adoptNode while appending should throw");
|
||||
}
|
||||
|
||||
var frag = document.createDocumentFragment();
|
||||
frag.appendChild(elem1);
|
||||
frag.appendChild(elem2);
|
||||
testAdoptFromDOMNodeRemoved(frag, elem1, elem2);
|
||||
|
||||
content.appendChild(elem1);
|
||||
testAdoptFromDOMNodeRemoved(elem1, elem1, content);
|
||||
|
||||
content.appendChild(elem1);
|
||||
|
||||
var thrown = false;
|
||||
|
||||
function changeOwnerDocument()
|
||||
{
|
||||
elem1.setUserData("foo", null, null);
|
||||
otherDoc.adoptNode(elem1);
|
||||
}
|
||||
elem1.setUserData("foo", "bar", changeOwnerDocument);
|
||||
try {
|
||||
document.adoptNode(elem1);
|
||||
}
|
||||
catch (e) {
|
||||
thrown = true;
|
||||
}
|
||||
|
||||
ok(thrown, "adoptNode while adopting should throw");
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user