Bug 395845. Fix leak of static parser-node cache. Patch by mrbkap. r/sr=sicking

This commit is contained in:
jonas@sicking.cc 2007-11-05 11:48:12 -08:00
Родитель 7d616bf099
Коммит 24549eb073
2 изменённых файлов: 45 добавлений и 70 удалений

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

@ -113,50 +113,6 @@ NS_IMPL_ISUPPORTS1(CViewSourceHTML, nsIDTD)
/********************************************
********************************************/
class CIndirectTextToken : public CTextToken {
public:
CIndirectTextToken() : CTextToken() {
mIndirectString=0;
}
void SetIndirectString(const nsSubstring& aString) {
mIndirectString=&aString;
}
virtual const nsSubstring& GetStringValue(void){
return (const nsSubstring&)*mIndirectString;
}
const nsSubstring* mIndirectString;
};
/*******************************************************************
Now define the CSharedVSCOntext class...
*******************************************************************/
class CSharedVSContext {
public:
CSharedVSContext() {
}
~CSharedVSContext() {
}
static CSharedVSContext& GetSharedContext() {
static CSharedVSContext gSharedVSContext;
return gSharedVSContext;
}
nsCParserNode mEndNode;
nsCParserStartNode mStartNode;
nsCParserStartNode mTokenNode;
CIndirectTextToken mITextToken;
nsCParserStartNode mErrorNode;
nsCParserNode mEndErrorNode;
};
enum {
kStartTag = 0,
kEndTag,
@ -724,9 +680,6 @@ nsresult CViewSourceHTML::WriteAttributes(PRInt32 attrCount, PRBool aOwnerInErro
nsresult result=NS_OK;
if(attrCount){ //go collect the attributes...
CSharedVSContext& theContext=CSharedVSContext::GetSharedContext();
int attr = 0;
for(attr = 0; attr < attrCount; ++attr){
CToken* theToken = mTokenizer->PeekToken();
@ -734,7 +687,7 @@ nsresult CViewSourceHTML::WriteAttributes(PRInt32 attrCount, PRBool aOwnerInErro
eHTMLTokenTypes theType = eHTMLTokenTypes(theToken->GetTokenType());
if(eToken_attribute == theType){
mTokenizer->PopToken(); //pop it for real...
theContext.mTokenNode.AddAttribute(theToken); //and add it to the node.
mTokenNode.AddAttribute(theToken); //and add it to the node.
CAttributeToken* theAttrToken = (CAttributeToken*)theToken;
const nsSubstring& theKey = theAttrToken->GetKey();
@ -775,8 +728,6 @@ nsresult CViewSourceHTML::WriteTag(PRInt32 aTagType,const nsSubstring & aText,PR
// types (bug 137315). So our line numbers will disagree with the parser's
// in some cases...
mLineNumber += aText.CountChar(PRUnichar('\n'));
CSharedVSContext& theContext=CSharedVSContext::GetSharedContext();
nsTokenAllocator* theAllocator=mTokenizer->GetTokenAllocator();
NS_ASSERTION(0!=theAllocator,"Error: no allocator");
@ -791,11 +742,11 @@ nsresult CViewSourceHTML::WriteTag(PRInt32 aTagType,const nsSubstring & aText,PR
eHTMLTag_span,
NS_LITERAL_STRING("SPAN")));
NS_ENSURE_TRUE(theTagToken, NS_ERROR_OUT_OF_MEMORY);
theContext.mErrorNode.Init(theTagToken, theAllocator);
AddAttrToNode(theContext.mErrorNode, theAllocator,
mErrorNode.Init(theTagToken, theAllocator);
AddAttrToNode(mErrorNode, theAllocator,
NS_LITERAL_STRING("class"),
NS_LITERAL_STRING("error"));
mSink->OpenContainer(theContext.mErrorNode);
mSink->OpenContainer(mErrorNode);
#ifdef DUMP_TO_FILE
if (gDumpFile) {
fprintf(gDumpFile, "<span class=\"error\">");
@ -805,8 +756,8 @@ nsresult CViewSourceHTML::WriteTag(PRInt32 aTagType,const nsSubstring & aText,PR
if (kBeforeText[aTagType][0] != 0) {
NS_ConvertASCIItoUTF16 beforeText(kBeforeText[aTagType]);
theContext.mITextToken.SetIndirectString(beforeText);
nsCParserNode theNode(&theContext.mITextToken, 0/*stack token*/);
mITextToken.SetIndirectString(beforeText);
nsCParserNode theNode(&mITextToken, 0/*stack token*/);
mSink->AddLeaf(theNode);
}
#ifdef DUMP_TO_FILE
@ -821,11 +772,11 @@ nsresult CViewSourceHTML::WriteTag(PRInt32 aTagType,const nsSubstring & aText,PR
eHTMLTag_span,
NS_LITERAL_STRING("SPAN")));
NS_ENSURE_TRUE(theTagToken, NS_ERROR_OUT_OF_MEMORY);
theContext.mStartNode.Init(theTagToken, theAllocator);
AddAttrToNode(theContext.mStartNode, theAllocator,
mStartNode.Init(theTagToken, theAllocator);
AddAttrToNode(mStartNode, theAllocator,
NS_LITERAL_STRING("class"),
NS_ConvertASCIItoUTF16(kElementClasses[aTagType]));
mSink->OpenContainer(theContext.mStartNode); //emit <starttag>...
mSink->OpenContainer(mStartNode); //emit <starttag>...
#ifdef DUMP_TO_FILE
if (gDumpFile) {
fprintf(gDumpFile, "<span class=\"");
@ -837,9 +788,9 @@ nsresult CViewSourceHTML::WriteTag(PRInt32 aTagType,const nsSubstring & aText,PR
STOP_TIMER();
theContext.mITextToken.SetIndirectString(aText); //now emit the tag name...
mITextToken.SetIndirectString(aText); //now emit the tag name...
nsCParserNode theNode(&theContext.mITextToken, 0/*stack token*/);
nsCParserNode theNode(&mITextToken, 0/*stack token*/);
mSink->AddLeaf(theNode);
#ifdef DUMP_TO_FILE
if (gDumpFile) {
@ -848,9 +799,9 @@ nsresult CViewSourceHTML::WriteTag(PRInt32 aTagType,const nsSubstring & aText,PR
#endif // DUMP_TO_FILE
if (mSyntaxHighlight && aTagType != kText) {
theContext.mStartNode.ReleaseAll();
mStartNode.ReleaseAll();
CEndToken theEndToken(eHTMLTag_span);
theContext.mEndNode.Init(&theEndToken, 0/*stack token*/);
mEndNode.Init(&theEndToken, 0/*stack token*/);
mSink->CloseContainer(eHTMLTag_span); //emit </endtag>...
#ifdef DUMP_TO_FILE
if (gDumpFile)
@ -866,8 +817,8 @@ nsresult CViewSourceHTML::WriteTag(PRInt32 aTagType,const nsSubstring & aText,PR
// the after-text
if (!aTagInError && kAfterText[aTagType][0] != 0) {
NS_ConvertASCIItoUTF16 afterText(kAfterText[aTagType]);
theContext.mITextToken.SetIndirectString(afterText);
nsCParserNode theNode(&theContext.mITextToken, 0/*stack token*/);
mITextToken.SetIndirectString(afterText);
nsCParserNode theNode(&mITextToken, 0/*stack token*/);
mSink->AddLeaf(theNode);
}
#ifdef DUMP_TO_FILE
@ -876,9 +827,9 @@ nsresult CViewSourceHTML::WriteTag(PRInt32 aTagType,const nsSubstring & aText,PR
#endif // DUMP_TO_FILE
if (mSyntaxHighlight && aTagInError) {
theContext.mErrorNode.ReleaseAll();
mErrorNode.ReleaseAll();
CEndToken theEndToken(eHTMLTag_span);
theContext.mEndErrorNode.Init(&theEndToken, 0/*stack token*/);
mEndErrorNode.Init(&theEndToken, 0/*stack token*/);
mSink->CloseContainer(eHTMLTag_span); //emit </endtag>...
#ifdef DUMP_TO_FILE
if (gDumpFile)
@ -906,8 +857,7 @@ NS_IMETHODIMP CViewSourceHTML::HandleToken(CToken* aToken,nsIParser* aParser)
mParser=(nsParser*)aParser;
mSink=(nsIHTMLContentSink*)aParser->GetContentSink();
CSharedVSContext& theContext=CSharedVSContext::GetSharedContext();
theContext.mTokenNode.Init(theToken, mTokenizer->GetTokenAllocator());
mTokenNode.Init(theToken, mTokenizer->GetTokenAllocator());
switch(theType) {
@ -917,7 +867,7 @@ NS_IMETHODIMP CViewSourceHTML::HandleToken(CToken* aToken,nsIParser* aParser)
result = WriteTag(kStartTag,startValue,aToken->GetAttributeCount(),aToken->IsInError());
if((ePlainText!=mDocType) && mParser && (NS_OK==result)) {
result = mSink->NotifyTagObservers(&theContext.mTokenNode);
result = mSink->NotifyTagObservers(&mTokenNode);
}
}
break;
@ -1022,7 +972,7 @@ NS_IMETHODIMP CViewSourceHTML::HandleToken(CToken* aToken,nsIParser* aParser)
result=NS_OK;
}//switch
theContext.mTokenNode.ReleaseAll();
mTokenNode.ReleaseAll();
return result;
}

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

@ -57,6 +57,24 @@ class nsParser;
class nsITokenizer;
class nsCParserNode;
class CIndirectTextToken : public CTextToken {
public:
CIndirectTextToken() : CTextToken() {
mIndirectString=0;
}
void SetIndirectString(const nsSubstring& aString) {
mIndirectString=&aString;
}
virtual const nsSubstring& GetStringValue(void){
return (const nsSubstring&)*mIndirectString;
}
const nsSubstring* mIndirectString;
};
class CViewSourceHTML: public nsIDTD
{
public:
@ -110,6 +128,13 @@ protected:
nsString mFilename;
PRUint32 mTokenCount;
nsCParserNode mEndNode;
nsCParserStartNode mStartNode;
nsCParserStartNode mTokenNode;
CIndirectTextToken mITextToken;
nsCParserStartNode mErrorNode;
nsCParserNode mEndErrorNode;
};
#endif