Bug 431082 - Crash [@ nsDocShell::DoChannelLoad], r+sr=bz

This commit is contained in:
Olli Pettay 2008-12-13 22:30:02 +02:00
Родитель ecd7e37c4e
Коммит e591911f63
6 изменённых файлов: 99 добавлений и 14 удалений

Просмотреть файл

@ -864,18 +864,20 @@ nsFrameLoader::EnsureDocShell()
NS_ASSERTION(frame_element, "frame loader owner element not a DOM element!");
nsCOMPtr<nsPIDOMWindow> win_private(do_GetInterface(mDocShell));
NS_ENSURE_TRUE(win_private, NS_ERROR_UNEXPECTED);
win_private->SetFrameElementInternal(frame_element);
nsCOMPtr<nsIBaseWindow> base_win(do_QueryInterface(mDocShell));
NS_ENSURE_TRUE(base_win, NS_ERROR_UNEXPECTED);
if (win_private) {
win_private->SetFrameElementInternal(frame_element);
}
// This is kinda whacky, this call doesn't really create anything,
// but it must be called to make sure things are properly
// initialized
base_win->Create();
// initialized...
if (NS_FAILED(base_win->Create()) || !win_private) {
// ...but if we couldn't create the shell properly, better
// to make sure it gets removed.
Destroy();
return NS_ERROR_FAILURE;
}
return NS_OK;
}

Просмотреть файл

@ -186,6 +186,7 @@ _TEST_FILES = test_bug5141.html \
file_htmlserializer_1_no_body.html \
test_bug424359-2.html \
file_htmlserializer_2.html \
test_bug431082.html \
file_htmlserializer_2_basic.html \
file_htmlserializer_2_enthtml.html \
file_htmlserializer_2_entw3c.html \

Просмотреть файл

@ -0,0 +1,52 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=431082
-->
<head>
<title>Test for Bug 431082</title>
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
<script type="text/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=431082">Mozilla Bug 431082</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script class="testbody" type="text/javascript">
/** Test for Bug 431082 **/
SimpleTest.waitForExplicitFinish();
addLoadEvent(function() { ok(true, "browser should not crash."); });
addLoadEvent(SimpleTest.finish);
</script>
</pre>
<!--
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<box id="a" observes="b">
<box id="b"/>
</box>
<box id="a" src="javascript:"/>
<box id="b" src="javascript://"/>
<editor observes="a"/>
<script>
function doe() {
window.addEventListener('DOMAttrModified', function()
{window.frameElement.parentNode.removeChild(window.frameElement);}, true);
document.documentElement.appendChild(document.getElementsByTagName('box')[0]);
}
setTimeout(doe,0);
</script>
</window>
-->
<iframe src="data:application/vnd.mozilla.xul+xml;charset=utf-8,%3Cwindow%20xmlns%3D%22http%3A//www.mozilla.org/keymaster/gatekeeper/there.is.only.xul%22%3E%0A%3Cbox%20%20id%3D%22a%22%20observes%3D%22b%22%3E%0A%20%20%3Cbox%20id%3D%22b%22/%3E%0A%3C/box%3E%0A%0A%3Cbox%20%20id%3D%22a%22%20%20src%3D%22javascript%3A%22/%3E%0A%3Cbox%20id%3D%22b%22%20src%3D%22javascript%3A//%22/%3E%0A%3Ceditor%20observes%3D%22a%22/%3E%0A%0A%3Cscript%3E%20%0Afunction%20doe%28%29%20%7B%0Awindow.addEventListener%28%27DOMAttrModified%27%2C%20function%28%29%20%7Bwindow.frameElement.parentNode.removeChild%28window.frameElement%29%3B%7D%2C%20true%29%3B%0Adocument.documentElement.appendChild%28document.getElementsByTagName%28%27box%27%29%5B0%5D%29%3B%0A%7D%0AsetTimeout%28doe%2C0%29%3B%0A%3C/script%3E%0A%3C/window%3E" style="width:1000px;height: 300px;"></iframe>
</body>
</html>

Просмотреть файл

@ -1854,6 +1854,7 @@ nsCSSFrameConstructor::nsCSSFrameConstructor(nsIDocument *aDocument,
, mGfxScrollFrame(nsnull)
, mPageSequenceFrame(nsnull)
, mUpdateCount(0)
, mFocusSuppressCount(0)
, mQuotesDirty(PR_FALSE)
, mCountersDirty(PR_FALSE)
, mIsDestroyingFrameTree(PR_FALSE)
@ -7674,7 +7675,7 @@ nsCSSFrameConstructor::ReconstructDocElementHierarchyInternal()
// RemoveMappingsForFrameSubtree() which would otherwise lead to a
// crash since we cleared the placeholder map above (bug 398982).
PRBool wasDestroyingFrameTree = mIsDestroyingFrameTree;
WillDestroyFrameTree();
WillDestroyFrameTree(PR_FALSE);
rv = state.mFrameManager->RemoveFrame(docElementFrame->GetParent(),
GetChildListNameFor(docElementFrame), docElementFrame);
@ -10164,6 +10165,7 @@ nsCSSFrameConstructor::AttributeChanged(nsIContent* aContent,
void
nsCSSFrameConstructor::BeginUpdate() {
NS_SuppressFocusEvent();
++mFocusSuppressCount;
++mUpdateCount;
}
@ -10177,8 +10179,10 @@ nsCSSFrameConstructor::EndUpdate()
RecalcQuotesAndCounters();
NS_ASSERTION(mUpdateCount == 1, "Odd update count");
}
if (mFocusSuppressCount) {
NS_UnsuppressFocusEvent();
--mUpdateCount;
--mFocusSuppressCount;
}
}
void
@ -10198,8 +10202,25 @@ nsCSSFrameConstructor::RecalcQuotesAndCounters()
NS_ASSERTION(!mCountersDirty, "Counter updates will be lost");
}
class nsFocusUnsuppressEvent : public nsRunnable {
public:
NS_DECL_NSIRUNNABLE
nsFocusUnsuppressEvent(PRUint32 aCount) : mCount(aCount) {}
private:
PRUint32 mCount;
};
NS_IMETHODIMP nsFocusUnsuppressEvent::Run()
{
while (mCount) {
--mCount;
NS_UnsuppressFocusEvent();
}
return NS_OK;
}
void
nsCSSFrameConstructor::WillDestroyFrameTree()
nsCSSFrameConstructor::WillDestroyFrameTree(PRBool aDestroyingPresShell)
{
#if defined(DEBUG_dbaron_off)
mCounterManager.Dump();
@ -10213,6 +10234,14 @@ nsCSSFrameConstructor::WillDestroyFrameTree()
// Cancel all pending re-resolves
mRestyleEvent.Revoke();
if (mFocusSuppressCount && aDestroyingPresShell) {
nsRefPtr<nsFocusUnsuppressEvent> ev =
new nsFocusUnsuppressEvent(mFocusSuppressCount);
if (NS_SUCCEEDED(NS_DispatchToCurrentThread(ev))) {
mFocusSuppressCount = 0;
}
}
}
//STATIC

Просмотреть файл

@ -154,7 +154,7 @@ public:
void EndUpdate();
void RecalcQuotesAndCounters();
void WillDestroyFrameTree();
void WillDestroyFrameTree(PRBool aDestroyingPresShell);
// Get an integer that increments every time there is a style change
// as a result of a change to the :hover content state.
@ -1193,6 +1193,7 @@ private:
nsQuoteList mQuoteList;
nsCounterManager mCounterManager;
PRUint16 mUpdateCount;
PRUint32 mFocusSuppressCount;
PRPackedBool mQuotesDirty : 1;
PRPackedBool mCountersDirty : 1;
PRPackedBool mIsDestroyingFrameTree : 1;

Просмотреть файл

@ -1705,7 +1705,7 @@ PresShell::Destroy()
CancelPostedReflowCallbacks();
// Destroy the frame manager. This will destroy the frame hierarchy
mFrameConstructor->WillDestroyFrameTree();
mFrameConstructor->WillDestroyFrameTree(PR_TRUE);
FrameManager()->Destroy();
NS_WARN_IF_FALSE(!mWeakFrames, "Weak frames alive after destroying FrameManager");