Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
AX: Crash: com.apple.WebKit.WebContent at com.apple.WebCore: WebCore:…
…:AXObjectCache::clearTextMarkerNodesInUse + 149 https://bugs.webkit.org/show_bug.cgi?id=139929 Reviewed by Darin Adler. Source/WebCore: When a frame is replaced, there were instances when it was not clearing its associated nodes in the accessibility text marker -> Node cache. This caused dead Nodes to be left in the cache which would eventually be accessed when the cache was cleaned out at a later time. To fix this we should be clearing out the cache in Document::prepareForDestruction, instead of Frame::disconnectOwnerElement. While working on this, it also exposed a problem where when a frame goes away, it doesn't inform its parent to update its children, which causes an ASSERT to be hit with this test as well. Tests: accessibility/frame-disconnect-textmarker-cache-crash.html * dom/Document.cpp: (WebCore::Document::prepareForDestruction): * page/Frame.cpp: (WebCore::Frame::disconnectOwnerElement): Remove cache management from here since it is superceded by code in Document::prepareForDestruction * page/FrameView.cpp: (WebCore::FrameView::removeFromAXObjectCache): LayoutTests: * accessibility/frame-disconnect-textmarker-cache-crash-expected.txt: Added. * accessibility/frame-disconnect-textmarker-cache-crash.html: Added. * accessibility/resources/frameset.html: Added. * accessibility/resources/inform-parent-of-load.html: Added. * accessibility/resources/text.html: Added. Canonical link: https://commits.webkit.org/158152@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@178038 268f45cc-cd09-0410-ab3c-d52691b4dbfc
- Loading branch information
Showing
with
164 additions
and 13 deletions.
- +13 −0 LayoutTests/ChangeLog
- +9 −0 LayoutTests/accessibility/frame-disconnect-textmarker-cache-crash-expected.txt
- +87 −0 LayoutTests/accessibility/frame-disconnect-textmarker-cache-crash.html
- +1 −0 LayoutTests/accessibility/resources/frameset.html
- +12 −0 LayoutTests/accessibility/resources/inform-parent-of-load.html
- +5 −0 LayoutTests/accessibility/resources/text.html
- +25 −0 Source/WebCore/ChangeLog
- +8 −0 Source/WebCore/dom/Document.cpp
- +0 −12 Source/WebCore/page/Frame.cpp
- +4 −1 Source/WebCore/page/FrameView.cpp
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@@ -0,0 +1,9 @@ | ||
This tests that when we access a text marker in a frame that is subsequently replaced by a different frame, we don't leave a hanging node in the cache that leads to a crash. | ||
|
||
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". | ||
|
||
|
||
PASS string is 'hello' | ||
PASS string is 'test text' | ||
TEST PASSED: NO CRASH | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@@ -0,0 +1,87 @@ | ||
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> | ||
<html> | ||
<head> | ||
<script src="../resources/js-test-pre.js"></script> | ||
</head> | ||
<body id="body"> | ||
|
||
<div id="content" role="group"> | ||
<iframe id="frame" src="resources/frameset.html" onload="frameLoad();" width=500 height=500></iframe> | ||
</div> | ||
|
||
<p id="description"></p> | ||
<div id="console"></div> | ||
|
||
<script> | ||
|
||
description("This tests that when we access a text marker in a frame that is subsequently replaced by a different frame, we don't leave a hanging node in the cache that leads to a crash."); | ||
|
||
var loadCount = 0; | ||
var markerRange = 0; | ||
var string = 0; | ||
|
||
function subFrameLoaded() { | ||
|
||
// Step 2: When the sub frame of the iframe loads again this method is called (from that sub-frame) | ||
|
||
// Access the old marker range that we kept hanging around and try to access after the frame changes. This should not crash. | ||
var frame = accessibilityController.accessibleElementById("content"); | ||
var webArea = frame.childAtIndex(0).childAtIndex(0); | ||
string = webArea.stringForTextMarkerRange(markerRange); | ||
|
||
// Now try to access a node in the sub-frame, and then we'll replace the parent frame. | ||
var text = frame.childAtIndex(0).childAtIndex(0).childAtIndex(0).childAtIndex(0).childAtIndex(0); | ||
// Access a marker range so that we start tracking a node in our cache. | ||
markerRange = text.textMarkerRangeForElement(text); | ||
string = text.stringForTextMarkerRange(markerRange); | ||
shouldBe("string", "'test text'"); | ||
|
||
// Step 3: Replace the top level iframe src while holding onto a marker range and verify there's no crash | ||
document.getElementById("frame").onload = function() { | ||
document.getElementById("content").removeChild(document.getElementById("frame")); | ||
string = accessibilityController.accessibleElementById("content").stringForTextMarkerRange(markerRange); | ||
|
||
debug("TEST PASSED: NO CRASH"); | ||
|
||
if (window.testRunner) { | ||
testRunner.notifyDone(); | ||
} | ||
gc(); | ||
}; | ||
|
||
document.getElementById("frame").src = "resources/text.html"; | ||
|
||
gc(); | ||
} | ||
|
||
function frameLoad() { | ||
|
||
// Step 1: When the iframe loads get a marker range that is reference is the sub-frame of the iframe. | ||
var frame = accessibilityController.accessibleElementById("content"); | ||
|
||
var text = frame.childAtIndex(0).childAtIndex(0).childAtIndex(0).childAtIndex(0).childAtIndex(0).childAtIndex(0); | ||
|
||
// Access a marker range so that we start tracking a node in our cache. | ||
markerRange = text.textMarkerRangeForElement(text); | ||
string = text.stringForTextMarkerRange(markerRange); | ||
|
||
shouldBe("string", "'hello'"); | ||
gc(); | ||
|
||
// Load a new frame in this location which should now invalidate the marker range cache (and not lead to a crash). | ||
document.getElementById("frame").contentWindow.frames[0].location = "resources/inform-parent-of-load.html"; | ||
|
||
gc(); | ||
} | ||
|
||
if (window.accessibilityController) { | ||
window.jsTestIsAsync = true; | ||
if (window.testRunner) | ||
testRunner.waitUntilDone(); | ||
} | ||
|
||
</script> | ||
|
||
<script src="../resources/js-test-post.js"></script> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@@ -0,0 +1 @@ | ||
<frameset rows='30%,70%'><frame src='text.html'><frame src='text.html'></frameset> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@@ -0,0 +1,12 @@ | ||
<html> | ||
<script> | ||
function informParent() { | ||
parent.parent.subFrameLoaded(); | ||
} | ||
</script> | ||
<body onload="informParent();"> | ||
|
||
test text | ||
|
||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@@ -0,0 +1,5 @@ | ||
<html> | ||
<body> | ||
<div role="group"><h1>hello</h1></div> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@@ -803,18 +803,6 @@ void Frame::willDetachPage() | ||
void Frame::disconnectOwnerElement() | ||
{ | ||
if (m_ownerElement) { | ||
m_ownerElement->clearContentFrame(); | ||
if (m_page) | ||
m_page->decrementSubframeCount(); | ||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters