Skip to content

Commit 8d714c8

Browse files
committed
document.importNode from standards to quirks mode document can result in broken selector matching
https://bugs.webkit.org/show_bug.cgi?id=289795 rdar://147548958 Reviewed by Ryosuke Niwa. Avoid sharing ElementData when cloning if one document has case folding behavior, and another doesn't. * LayoutTests/fast/dom/importNode-quirks-class-sharing-expected.txt: Added. * LayoutTests/fast/dom/importNode-quirks-class-sharing.html: Added. * Source/WebCore/dom/Element.cpp: (WebCore::Element::cloneAttributesFromElement): Canonical link: https://commits.webkit.org/292542@main
1 parent bad02c7 commit 8d714c8

3 files changed

Lines changed: 68 additions & 1 deletion

File tree

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
Test that cloning elements between quirks and no-quirks document handles case folding properly
2+
3+
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
4+
5+
6+
PASS document.compatMode is 'CSS1Compat'
7+
PASS quirksFrame.contentDocument.compatMode is 'BackCompat'
8+
PASS noQuirksFrame.contentDocument.compatMode is 'CSS1Compat'
9+
PASS quirksFrame.contentDocument.querySelector('.pageContentClass') is sectionElementImportedToQuirksDocument
10+
PASS quirksFrame.contentDocument.querySelector('.pagecontentclass') is sectionElementImportedToQuirksDocument
11+
PASS document.querySelector('.pageContentClass') is sectionElement
12+
PASS noQuirksFrame.contentDocument.querySelector('.pageContentClass') is sectionElementImportedToNoQuirksDocument
13+
PASS quirksFrame.contentDocument.querySelector('.pageContentClass') is sectionElementImportedToQuirksDocument
14+
PASS quirksFrame.contentDocument.querySelector('.pagecontentclass') is sectionElementImportedToQuirksDocument
15+
PASS successfullyParsed is true
16+
17+
TEST COMPLETE
18+
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8">
5+
<script src="../../resources/js-test.js"></script>
6+
</head>
7+
<body>
8+
<section id="pageContent" class="pageContentClass"></section>
9+
<iframe id="quirksFrame" src="about:blank" style="display:none"></iframe>
10+
<script>
11+
12+
description("Test that cloning elements between quirks and no-quirks document handles case folding properly");
13+
14+
var quirksFrame = document.getElementById("quirksFrame");
15+
16+
var noQuirksFrame = document.createElement("iframe");
17+
noQuirksFrame.srcdoc = "<!DOCTYPE html><html><head></head><body></body></html>";
18+
noQuirksFrame.style = "display:none";
19+
document.body.appendChild(noQuirksFrame);
20+
21+
onload = function() {
22+
23+
// Sanity check.
24+
shouldBe("document.compatMode", "'CSS1Compat'");
25+
shouldBe("quirksFrame.contentDocument.compatMode", "'BackCompat'");
26+
shouldBe("noQuirksFrame.contentDocument.compatMode", "'CSS1Compat'");
27+
28+
// Test that cloning from standards mode to quirks mode doesn't mutate the original.
29+
sectionElement = document.getElementById("pageContent");
30+
sectionElementImportedToQuirksDocument = quirksFrame.contentDocument.importNode(sectionElement);
31+
quirksFrame.contentDocument.body.appendChild(sectionElementImportedToQuirksDocument);
32+
shouldBe("quirksFrame.contentDocument.querySelector('.pageContentClass')", "sectionElementImportedToQuirksDocument");
33+
shouldBe("quirksFrame.contentDocument.querySelector('.pagecontentclass')", "sectionElementImportedToQuirksDocument");
34+
shouldBe("document.querySelector('.pageContentClass')", "sectionElement");
35+
36+
// Same for cloning from quirks to no-quirks.
37+
sectionElementImportedToNoQuirksDocument = noQuirksFrame.contentDocument.importNode(sectionElementImportedToQuirksDocument);
38+
noQuirksFrame.contentDocument.body.appendChild(sectionElementImportedToNoQuirksDocument);
39+
shouldBe("noQuirksFrame.contentDocument.querySelector('.pageContentClass')", "sectionElementImportedToNoQuirksDocument");
40+
shouldBe("quirksFrame.contentDocument.querySelector('.pageContentClass')", "sectionElementImportedToQuirksDocument");
41+
shouldBe("quirksFrame.contentDocument.querySelector('.pagecontentclass')", "sectionElementImportedToQuirksDocument");
42+
}
43+
44+
</script>
45+
</body>
46+
</html>

Source/WebCore/dom/Element.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5650,7 +5650,10 @@ void Element::cloneAttributesFromElement(const Element& other)
56505650
&& (!uniqueElementData->inlineStyle() || !uniqueElementData->inlineStyle()->hasCSSOMWrapper()))
56515651
const_cast<Element&>(other).m_elementData = uniqueElementData->makeShareableCopy();
56525652

5653-
if (!other.m_elementData->isUnique())
5653+
bool canShareElementData = !other.m_elementData->isUnique()
5654+
&& (document().inQuirksMode() == other.document().inQuirksMode()); // Case folding in quirks mode documents can mutate element data.
5655+
5656+
if (canShareElementData)
56545657
m_elementData = other.m_elementData;
56555658
else
56565659
m_elementData = other.m_elementData->makeUniqueCopy();

0 commit comments

Comments
 (0)