From de636441d927233af40f2788f534287fd0d8a009 Mon Sep 17 00:00:00 2001 From: "kmcclusk%netscape.com" Date: Wed, 7 Nov 2001 01:02:56 +0000 Subject: [PATCH] Fix leak of parser objects when page load is interrupted by calling nsParser::CancelParsingEvents inside nsParser::Terminate; bug 108049 (patch from aaronr@us.ibm.com) r=harishd sr=attinasi --- htmlparser/src/nsParser.cpp | 14 ++++++++++++++ parser/htmlparser/src/nsParser.cpp | 14 ++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/htmlparser/src/nsParser.cpp b/htmlparser/src/nsParser.cpp index dee54a0a21eb..4485ef06e054 100644 --- a/htmlparser/src/nsParser.cpp +++ b/htmlparser/src/nsParser.cpp @@ -1320,7 +1320,13 @@ nsParser::CancelParsingEvents() { if (mEventQueue != nsnull) { mEventQueue->RevokeEvents(this); } + mPendingContinueEvent=PR_FALSE; + /* Since we are taking this off of the queue, we need to do the NS_RELEASE + * that nsParserContinueEvent::HandleEvent would have done. + */ + nsParser* me = this; + NS_RELEASE(me); } return NS_OK; } @@ -1454,6 +1460,14 @@ nsresult nsParser::Terminate(void){ // Hack - Hold a reference until we are completely done... nsCOMPtr kungFuDeathGrip(this); mInternalState=result; + + // CancelParsingEvents must be called to avoid leaking the nsParser object + // @see bug 108049 + // If mPendingContinueEvents is PR_TRUE CancelParsingEvents will reset + // the mPendingContinueEvent to PR_FALSE so DidBuildModel will call + // DidBuildModel on the DTD. Note: The IsComplete() call inside of DidBuildModel + // looks at the mPendingContinueEvents flag. + CancelParsingEvents(); DidBuildModel(result); } } diff --git a/parser/htmlparser/src/nsParser.cpp b/parser/htmlparser/src/nsParser.cpp index dee54a0a21eb..4485ef06e054 100644 --- a/parser/htmlparser/src/nsParser.cpp +++ b/parser/htmlparser/src/nsParser.cpp @@ -1320,7 +1320,13 @@ nsParser::CancelParsingEvents() { if (mEventQueue != nsnull) { mEventQueue->RevokeEvents(this); } + mPendingContinueEvent=PR_FALSE; + /* Since we are taking this off of the queue, we need to do the NS_RELEASE + * that nsParserContinueEvent::HandleEvent would have done. + */ + nsParser* me = this; + NS_RELEASE(me); } return NS_OK; } @@ -1454,6 +1460,14 @@ nsresult nsParser::Terminate(void){ // Hack - Hold a reference until we are completely done... nsCOMPtr kungFuDeathGrip(this); mInternalState=result; + + // CancelParsingEvents must be called to avoid leaking the nsParser object + // @see bug 108049 + // If mPendingContinueEvents is PR_TRUE CancelParsingEvents will reset + // the mPendingContinueEvent to PR_FALSE so DidBuildModel will call + // DidBuildModel on the DTD. Note: The IsComplete() call inside of DidBuildModel + // looks at the mPendingContinueEvents flag. + CancelParsingEvents(); DidBuildModel(result); } }