From 512157dd9d0d254a708479b5cae9d2533cef6547 Mon Sep 17 00:00:00 2001 From: "rickg%netscape.com" Date: Fri, 10 Dec 1999 04:01:26 +0000 Subject: [PATCH] This fixes PDT+Bug:20228. The essential problem was the lack of refcounting on tokenizers. Also fixed unchecked dereferences in expattokenizer. r=kmcclusk; a=chofmann. --- htmlparser/src/CNavDTD.cpp | 8 ++-- htmlparser/src/nsExpatDTD.cpp | 5 +-- htmlparser/src/nsExpatTokenizer.cpp | 41 +++++++++++++------ htmlparser/src/nsExpatTokenizer.h | 11 +++++- htmlparser/src/nsHTMLTokenizer.cpp | 46 +++++++++++----------- htmlparser/src/nsHTMLTokenizer.h | 4 +- htmlparser/src/nsViewSourceHTML.cpp | 8 ++-- htmlparser/src/nsWellFormedDTD.cpp | 8 ++-- htmlparser/src/nsXIFDTD.cpp | 7 +++- htmlparser/src/nsXMLTokenizer.cpp | 6 +-- htmlparser/src/nsXMLTokenizer.h | 2 +- parser/htmlparser/src/CNavDTD.cpp | 8 ++-- parser/htmlparser/src/nsExpatDTD.cpp | 5 +-- parser/htmlparser/src/nsExpatTokenizer.cpp | 41 +++++++++++++------ parser/htmlparser/src/nsExpatTokenizer.h | 11 +++++- parser/htmlparser/src/nsHTMLTokenizer.cpp | 46 +++++++++++----------- parser/htmlparser/src/nsHTMLTokenizer.h | 4 +- parser/htmlparser/src/nsViewSourceHTML.cpp | 8 ++-- parser/htmlparser/src/nsWellFormedDTD.cpp | 8 ++-- parser/htmlparser/src/nsXIFDTD.cpp | 7 +++- parser/htmlparser/src/nsXMLTokenizer.cpp | 6 +-- parser/htmlparser/src/nsXMLTokenizer.h | 2 +- 22 files changed, 180 insertions(+), 112 deletions(-) diff --git a/htmlparser/src/CNavDTD.cpp b/htmlparser/src/CNavDTD.cpp index 23561597ed4d..fcec3126bc0a 100644 --- a/htmlparser/src/CNavDTD.cpp +++ b/htmlparser/src/CNavDTD.cpp @@ -333,8 +333,7 @@ CNavDTD::~CNavDTD(){ delete mHeadContext; delete mBodyContext; - if(mTokenizer) - delete (nsHTMLTokenizer*)mTokenizer; + NS_IF_RELEASE(mTokenizer); if(mTempContext) delete mTempContext; @@ -3316,8 +3315,9 @@ nsITokenRecycler* CNavDTD::GetTokenRecycler(void){ * @return ptr to tokenizer */ nsITokenizer* CNavDTD::GetTokenizer(void) { - if(!mTokenizer) - mTokenizer=new nsHTMLTokenizer(mParseMode); + if(!mTokenizer) { + nsresult result=NS_NewHTMLTokenizer(&mTokenizer); + } return mTokenizer; } diff --git a/htmlparser/src/nsExpatDTD.cpp b/htmlparser/src/nsExpatDTD.cpp index d6a619a6bed2..1789039c794f 100644 --- a/htmlparser/src/nsExpatDTD.cpp +++ b/htmlparser/src/nsExpatDTD.cpp @@ -136,8 +136,7 @@ nsExpatDTD::nsExpatDTD() : nsIDTD(), mFilename("") { */ nsExpatDTD::~nsExpatDTD(){ mParser=0; //just to prove we destructed... - if(mTokenizer) - delete (nsExpatTokenizer*)mTokenizer; + NS_IF_RELEASE(mTokenizer); if (mExpatParser) XML_ParserFree(mExpatParser); } @@ -328,7 +327,7 @@ void nsExpatDTD::SetupExpatCallbacks(void) { */ nsITokenizer* nsExpatDTD::GetTokenizer(void) { if(!mTokenizer) { - mTokenizer=new nsExpatTokenizer(); + nsresult result=NS_New_Expat_Tokenizer(&mTokenizer); mExpatParser = XML_ParserCreate(NULL); if (mExpatParser) { SetupExpatCallbacks(); diff --git a/htmlparser/src/nsExpatTokenizer.cpp b/htmlparser/src/nsExpatTokenizer.cpp index 67f9ecd7f218..5cd3cdd8a6ee 100644 --- a/htmlparser/src/nsExpatTokenizer.cpp +++ b/htmlparser/src/nsExpatTokenizer.cpp @@ -58,6 +58,21 @@ static const char* kDocTypeDeclPrefix = "SetError(error); CToken* theToken = (CToken* )token; - AddToken(theToken, NS_OK, *gTokenDeque,gTokenRecycler); + AddToken(theToken, NS_OK, gTokenDeque,gTokenRecycler); } } @@ -290,6 +306,9 @@ nsresult nsExpatTokenizer::ParseXMLBuffer(const char* aBuffer, PRUint32 aLength, nsresult result=NS_OK; PR_ASSERT((aBuffer && aLength) || (aBuffer == nsnull && aLength == 0)); if (mExpatParser) { + + nsCOMPtr me=this; + if (!XML_Parse(mExpatParser, aBuffer, aLength, aIsFinal)) { PushXMLErrorToken(aBuffer, aLength, aIsFinal); result=NS_ERROR_HTMLPARSER_STOPPARSING; @@ -365,7 +384,7 @@ void nsExpatTokenizer::HandleStartElement(void *userData, const XML_Char *name, if(theToken) { nsString& theString=theToken->GetStringValueXXX(); theString.SetString((PRUnichar *) name); - AddToken(theToken,NS_OK,*gTokenDeque,gTokenRecycler); + AddToken(theToken,NS_OK,gTokenDeque,gTokenRecycler); int theAttrCount=0; while(*atts){ theAttrCount++; @@ -377,7 +396,7 @@ void nsExpatTokenizer::HandleStartElement(void *userData, const XML_Char *name, theValue.SetString((PRUnichar *) (*atts++)); } CToken* theTok=(CToken*)theAttrToken; - AddToken(theTok,NS_OK,*gTokenDeque,gTokenRecycler); + AddToken(theTok,NS_OK,gTokenDeque,gTokenRecycler); } theToken->SetAttributeCount(theAttrCount); } @@ -391,7 +410,7 @@ void nsExpatTokenizer::HandleEndElement(void *userData, const XML_Char *name) { if(theToken) { nsString& theString=theToken->GetStringValueXXX(); theString.SetString((PRUnichar *) name); - AddToken(theToken,NS_OK,*gTokenDeque,gTokenRecycler); + AddToken(theToken,NS_OK,gTokenDeque,gTokenRecycler); } else{ //THROW A HUGE ERROR IF WE CANT CREATE A TOKEN! @@ -425,7 +444,7 @@ void nsExpatTokenizer::HandleCharacterData(void *userData, const XML_Char *s, in nsString& theString=newToken->GetStringValueXXX(); theString.Append((PRUnichar *) s,len); } - AddToken(newToken,NS_OK,*gTokenDeque,gTokenRecycler); + AddToken(newToken,NS_OK,gTokenDeque,gTokenRecycler); } else { //THROW A HUGE ERROR IF WE CANT CREATE A TOKEN! @@ -438,7 +457,7 @@ void nsExpatTokenizer::HandleComment(void *userData, const XML_Char *name) { if(theToken) { nsString& theString=theToken->GetStringValueXXX(); theString.SetString((PRUnichar *) name); - AddToken(theToken,NS_OK,*gTokenDeque,gTokenRecycler); + AddToken(theToken,NS_OK,gTokenDeque,gTokenRecycler); } else{ //THROW A HUGE ERROR IF WE CANT CREATE A TOKEN! @@ -457,7 +476,7 @@ void nsExpatTokenizer::HandleEndCdataSection(void *userData) { // We've reached the end of the current CDATA section. Push the current // CDATA token onto the token queue - AddToken(currentCDataToken,NS_OK,*gTokenDeque,gTokenRecycler); + AddToken(currentCDataToken,NS_OK,gTokenDeque,gTokenRecycler); XML_SetUserData(gExpatParser, nsnull); } @@ -473,7 +492,7 @@ void nsExpatTokenizer::HandleProcessingInstruction(void *userData, const XML_Cha theString.Append((PRUnichar *) data); } theString.Append("?>"); - AddToken(theToken,NS_OK,*gTokenDeque,gTokenRecycler); + AddToken(theToken,NS_OK,gTokenDeque,gTokenRecycler); } else{ //THROW A HUGE ERROR IF WE CANT CREATE A TOKEN! @@ -487,7 +506,7 @@ void nsExpatTokenizer::HandleDefault(void *userData, const XML_Char *s, int len) while ((offset = str.FindChar('\n', PR_FALSE, offset + 1)) != -1) { newLine = gTokenRecycler->CreateTokenOfType(eToken_newline, eHTMLTag_unknown); - AddToken(newLine, NS_OK, *gTokenDeque, gTokenRecycler); + AddToken(newLine, NS_OK, gTokenDeque, gTokenRecycler); } } @@ -705,7 +724,7 @@ void nsExpatTokenizer::HandleStartDoctypeDecl(void *userData, str.Append(" "); str.Append((PRUnichar*) doctypeName); str.Append(">"); - AddToken(token,NS_OK,*gTokenDeque,gTokenRecycler); + AddToken(token,NS_OK,gTokenDeque,gTokenRecycler); } } diff --git a/htmlparser/src/nsExpatTokenizer.h b/htmlparser/src/nsExpatTokenizer.h index 2a12fa6141ad..78308d700ac4 100644 --- a/htmlparser/src/nsExpatTokenizer.h +++ b/htmlparser/src/nsExpatTokenizer.h @@ -42,6 +42,12 @@ {0x483836aa, 0xcabe, 0x11d2, { 0xab, 0xcb, 0x0, 0x10, 0x4b, 0x98, 0x3f, 0xd4 }} +// {575C063A-AE9C-11d3-B9FD-001083023C0E} +#define NS_EXPATTOKENIZER_CID \ +{ 0x575c063a, 0xae9c, 0x11d3, \ + {0xb9, 0xfd, 0x0, 0x10, 0x83, 0x2, 0x3c, 0xe}} + + /*************************************************************** Notes: ***************************************************************/ @@ -55,6 +61,9 @@ public: nsExpatTokenizer(nsString* aURL = nsnull); virtual ~nsExpatTokenizer(); + virtual const nsIID& GetCID(); + static const nsIID& GetIID(); + NS_DECL_ISUPPORTS /* nsITokenizer methods */ @@ -136,6 +145,6 @@ protected: nsString mLastLine; }; -extern NS_HTMLPARS nsresult NS_Expat_Tokenizer(nsIDTD** aInstancePtrResult); +extern NS_HTMLPARS nsresult NS_New_Expat_Tokenizer(nsITokenizer** aInstancePtrResult); #endif diff --git a/htmlparser/src/nsHTMLTokenizer.cpp b/htmlparser/src/nsHTMLTokenizer.cpp index dfc0558a044a..e81ec0230be2 100644 --- a/htmlparser/src/nsHTMLTokenizer.cpp +++ b/htmlparser/src/nsHTMLTokenizer.cpp @@ -85,20 +85,22 @@ nsHTMLTokenizer::FreeTokenRecycler(void) { } /** - * This method is defined in nsIParser. It is used to - * cause the COM-like construction of an nsParser. + * This method is defined in nsHTMLTokenizer.h. It is used to + * cause the COM-like construction of an HTMLTokenizer. * * @update gess 4/8/98 * @param nsIParser** ptr to newly instantiated parser * @return NS_xxx error result */ -NS_HTMLPARS nsresult NS_NewHTMLTokenizer(nsIDTD** aInstancePtrResult) { +NS_HTMLPARS nsresult NS_NewHTMLTokenizer(nsITokenizer** aInstancePtrResult) { + NS_PRECONDITION(nsnull != aInstancePtrResult, "null ptr"); + if (nsnull == aInstancePtrResult) { + return NS_ERROR_NULL_POINTER; + } nsHTMLTokenizer* it = new nsHTMLTokenizer(); - - if (it == 0) { + if (nsnull == it) { return NS_ERROR_OUT_OF_MEMORY; } - return it->QueryInterface(kClassIID, (void **) aInstancePtrResult); } @@ -142,10 +144,10 @@ nsHTMLTokenizer::~nsHTMLTokenizer(){ Here begins the real working methods for the tokenizer. *******************************************************************/ -void nsHTMLTokenizer::AddToken(CToken*& aToken,nsresult aResult,nsDeque& aDeque,CTokenRecycler* aRecycler) { - if(aToken) { +void nsHTMLTokenizer::AddToken(CToken*& aToken,nsresult aResult,nsDeque* aDeque,CTokenRecycler* aRecycler) { + if(aToken && aDeque) { if(NS_SUCCEEDED(aResult)) { - aDeque.Push(aToken); + aDeque->Push(aToken); } else { if(aRecycler) { @@ -423,7 +425,7 @@ nsresult nsHTMLTokenizer::ConsumeAttributes(PRUnichar aChar,CStartToken* aToken, } else { theAttrCount++; - AddToken(theToken,result,mTokenDeque,theRecycler); + AddToken(theToken,result,&mTokenDeque,theRecycler); } } else { //if(NS_ERROR_HTMLPARSER_BADATTRIBUTE==result){ @@ -447,7 +449,7 @@ nsresult nsHTMLTokenizer::ConsumeAttributes(PRUnichar aChar,CStartToken* aToken, eHTMLTags theEndTag = (eHTMLTags)aToken->GetTypeID(); if(result==NS_OK&&(gHTMLElements[theEndTag].mSkipTarget)){ CToken* theEndToken=theRecycler->CreateTokenOfType(eToken_end,theEndTag); - AddToken(theEndToken,NS_OK,mTokenDeque,theRecycler); + AddToken(theEndToken,NS_OK,&mTokenDeque,theRecycler); } done=PR_TRUE; } @@ -490,7 +492,7 @@ nsresult nsHTMLTokenizer::ConsumeStartTag(PRUnichar aChar,CToken*& aToken,nsScan result= aToken->Consume(aChar,aScanner,mParseMode); //tell new token to finish consuming text... if(NS_SUCCEEDED(result)) { - AddToken(aToken,result,mTokenDeque,theRecycler); + AddToken(aToken,result,&mTokenDeque,theRecycler); eHTMLTags theTag=(eHTMLTags)aToken->GetTypeID(); if(((CStartToken*)aToken)->IsAttributed()) { @@ -512,8 +514,8 @@ nsresult nsHTMLTokenizer::ConsumeStartTag(PRUnichar aChar,CToken*& aToken,nsScan result=((CTextToken*)textToken)->ConsumeUntil(0,PR_TRUE,aScanner,endTag,mParseMode); //tell new token to finish consuming text... //endTag.Append(">"); CToken* endToken=theRecycler->CreateTokenOfType(eToken_end,theTag,endTag); - AddToken(textToken,result,mTokenDeque,theRecycler); - AddToken(endToken,result,mTokenDeque,theRecycler); + AddToken(textToken,result,&mTokenDeque,theRecycler); + AddToken(endToken,result,&mTokenDeque,theRecycler); } } @@ -548,7 +550,7 @@ nsresult nsHTMLTokenizer::ConsumeEndTag(PRUnichar aChar,CToken*& aToken,nsScanne if(aToken) { result= aToken->Consume(aChar,aScanner,mParseMode); //tell new token to finish consuming text... - AddToken(aToken,result,mTokenDeque,theRecycler); + AddToken(aToken,result,&mTokenDeque,theRecycler); } //if return result; } @@ -594,7 +596,7 @@ nsresult nsHTMLTokenizer::ConsumeEntity(PRUnichar aChar,CToken*& aToken,nsScanne theRecycler->RecycleToken(aToken); aToken=theToken; } - AddToken(aToken,result,mTokenDeque,theRecycler); + AddToken(aToken,result,&mTokenDeque,theRecycler); } }//if return result; @@ -617,7 +619,7 @@ nsresult nsHTMLTokenizer::ConsumeWhitespace(PRUnichar aChar,CToken*& aToken,nsSc nsresult result=NS_OK; if(aToken) { result=aToken->Consume(aChar,aScanner,mParseMode); - AddToken(aToken,result,mTokenDeque,theRecycler); + AddToken(aToken,result,&mTokenDeque,theRecycler); } return result; } @@ -638,7 +640,7 @@ nsresult nsHTMLTokenizer::ConsumeComment(PRUnichar aChar,CToken*& aToken,nsScann nsresult result=NS_OK; if(aToken) { result=aToken->Consume(aChar,aScanner,mParseMode); - AddToken(aToken,result,mTokenDeque,theRecycler); + AddToken(aToken,result,&mTokenDeque,theRecycler); } return result; } @@ -668,7 +670,7 @@ nsresult nsHTMLTokenizer::ConsumeText(const nsString& aString,CToken*& aToken,ns } else result=NS_OK; } - AddToken(aToken,result,mTokenDeque,theRecycler); + AddToken(aToken,result,&mTokenDeque,theRecycler); } return result; } @@ -703,7 +705,7 @@ nsresult nsHTMLTokenizer::ConsumeSpecialMarkup(PRUnichar aChar,CToken*& aToken,n if(aToken) { result=aToken->Consume(aChar,aScanner,mParseMode); - AddToken(aToken,result,mTokenDeque,theRecycler); + AddToken(aToken,result,&mTokenDeque,theRecycler); } return result; } @@ -723,7 +725,7 @@ nsresult nsHTMLTokenizer::ConsumeNewline(PRUnichar aChar,CToken*& aToken,nsScann nsresult result=NS_OK; if(aToken) { result=aToken->Consume(aChar,aScanner,mParseMode); - AddToken(aToken,result,mTokenDeque,theRecycler); + AddToken(aToken,result,&mTokenDeque,theRecycler); } return result; } @@ -744,7 +746,7 @@ nsresult nsHTMLTokenizer::ConsumeProcessingInstruction(PRUnichar aChar,CToken*& nsresult result=NS_OK; if(aToken) { result=aToken->Consume(aChar,aScanner,mParseMode); - AddToken(aToken,result,mTokenDeque,theRecycler); + AddToken(aToken,result,&mTokenDeque,theRecycler); } return result; } diff --git a/htmlparser/src/nsHTMLTokenizer.h b/htmlparser/src/nsHTMLTokenizer.h index bee7ff772cdc..4b88ab470c4e 100644 --- a/htmlparser/src/nsHTMLTokenizer.h +++ b/htmlparser/src/nsHTMLTokenizer.h @@ -91,7 +91,7 @@ protected: virtual void RecordTrailingContent(CStartToken* aStartToken,nsScanner& aScanner); - static void AddToken(CToken*& aToken,nsresult aResult,nsDeque& aDeque,CTokenRecycler* aRecycler); + static void AddToken(CToken*& aToken,nsresult aResult,nsDeque* aDeque,CTokenRecycler* aRecycler); nsDeque mTokenDeque; PRBool mDoXMLEmptyTags; @@ -99,7 +99,7 @@ protected: PRBool mPlainText; }; -extern NS_HTMLPARS nsresult NS_NewHTMLTokenizer(nsIDTD** aInstancePtrResult); +extern NS_HTMLPARS nsresult NS_NewHTMLTokenizer(nsITokenizer** aInstancePtrResult); #endif diff --git a/htmlparser/src/nsViewSourceHTML.cpp b/htmlparser/src/nsViewSourceHTML.cpp index a53fffc72464..b38d05b0ac10 100644 --- a/htmlparser/src/nsViewSourceHTML.cpp +++ b/htmlparser/src/nsViewSourceHTML.cpp @@ -234,6 +234,9 @@ CViewSourceHTML::CViewSourceHTML() : nsIDTD(), */ CViewSourceHTML::~CViewSourceHTML(){ mParser=0; //just to prove we destructed... + + NS_IF_RELEASE(mTokenizer); + } /** @@ -448,8 +451,7 @@ nsITokenRecycler* CViewSourceHTML::GetTokenRecycler(void){ * @param * @return */ -nsresult CViewSourceHTML::Terminate(void) -{ +nsresult CViewSourceHTML::Terminate(void) { return NS_ERROR_HTMLPARSER_STOPPARSING; } @@ -461,7 +463,7 @@ nsresult CViewSourceHTML::Terminate(void) */ nsITokenizer* CViewSourceHTML::GetTokenizer(void) { if(!mTokenizer) { - mTokenizer = new nsHTMLTokenizer(eParseMode_quirks,mIsText); + nsresult result=NS_NewHTMLTokenizer(&mTokenizer); } return mTokenizer; } diff --git a/htmlparser/src/nsWellFormedDTD.cpp b/htmlparser/src/nsWellFormedDTD.cpp index 30063b3fbba2..bdb3c98c3ada 100644 --- a/htmlparser/src/nsWellFormedDTD.cpp +++ b/htmlparser/src/nsWellFormedDTD.cpp @@ -143,9 +143,7 @@ CWellFormedDTD::CWellFormedDTD() : nsIDTD(), mFilename("") { */ CWellFormedDTD::~CWellFormedDTD(){ mParser=0; //just to prove we destructed... - if (mTokenizer) - delete mTokenizer; - mTokenizer=0; + NS_IF_RELEASE(mTokenizer); } /** @@ -350,8 +348,10 @@ nsresult CWellFormedDTD::Terminate(void) * @return ptr to tokenizer */ nsITokenizer* CWellFormedDTD::GetTokenizer(void) { - if(!mTokenizer) + if(!mTokenizer) { mTokenizer=(nsHTMLTokenizer*)new nsExpatTokenizer(&mFilename); + NS_IF_ADDREF(mTokenizer); + } return mTokenizer; } diff --git a/htmlparser/src/nsXIFDTD.cpp b/htmlparser/src/nsXIFDTD.cpp index 10222cf66cc9..4e1c759dca19 100644 --- a/htmlparser/src/nsXIFDTD.cpp +++ b/htmlparser/src/nsXIFDTD.cpp @@ -264,6 +264,7 @@ nsXIFDTD::nsXIFDTD() : nsIDTD(){ */ nsXIFDTD::~nsXIFDTD(){ NS_IF_RELEASE(mSink); + NS_IF_RELEASE(mTokenizer); } @@ -1223,11 +1224,13 @@ nsresult nsXIFDTD::AddLeaf(const nsIParserNode& aNode) * @return */ nsITokenizer* nsXIFDTD::GetTokenizer(void){ - if(!mTokenizer) - mTokenizer=new nsXMLTokenizer(); + if(!mTokenizer) { + nsresult result=NS_NewXMLTokenizer(&mTokenizer); + } return mTokenizer; } + /** * * @update gess8/4/98 diff --git a/htmlparser/src/nsXMLTokenizer.cpp b/htmlparser/src/nsXMLTokenizer.cpp index 72ee27c7218a..28ed5c45a09c 100644 --- a/htmlparser/src/nsXMLTokenizer.cpp +++ b/htmlparser/src/nsXMLTokenizer.cpp @@ -91,7 +91,7 @@ nsXMLTokenizer::FreeTokenRecycler(void) { * @param nsIParser** ptr to newly instantiated parser * @return NS_xxx error result */ -NS_HTMLPARS nsresult NS_NewXMLTokenizer(nsIDTD** aInstancePtrResult) { +NS_HTMLPARS nsresult NS_NewXMLTokenizer(nsITokenizer** aInstancePtrResult){ nsXMLTokenizer* it = new nsXMLTokenizer(); if (it == 0) { @@ -208,7 +208,7 @@ nsresult nsXMLTokenizer::ConsumeComment(PRUnichar aChar,CToken*& aToken,nsScanne aToken=theRecycler->CreateTokenOfType(eToken_comment,eHTMLTag_comment,theEmpty); if(aToken) { result=aToken->Consume(aChar,aScanner,eParseMode_noquirks); - AddToken(aToken,result,mTokenDeque,theRecycler); + AddToken(aToken,result,&mTokenDeque,theRecycler); } } @@ -251,7 +251,7 @@ nsresult nsXMLTokenizer::ConsumeSpecialMarkup(PRUnichar aChar,CToken*& aToken,ns if(aToken) { result=aToken->Consume(aChar,aScanner,eParseMode_noquirks); - AddToken(aToken,result,mTokenDeque,theRecycler); + AddToken(aToken,result,&mTokenDeque,theRecycler); } } return result; diff --git a/htmlparser/src/nsXMLTokenizer.h b/htmlparser/src/nsXMLTokenizer.h index 6c198af6b0dc..0ce0486db8a3 100644 --- a/htmlparser/src/nsXMLTokenizer.h +++ b/htmlparser/src/nsXMLTokenizer.h @@ -72,7 +72,7 @@ protected: }; -extern NS_HTMLPARS nsresult NS_NewXMLTokenizer(nsIDTD** aInstancePtrResult); +extern NS_HTMLPARS nsresult NS_NewXMLTokenizer(nsITokenizer** aInstancePtrResult); #endif diff --git a/parser/htmlparser/src/CNavDTD.cpp b/parser/htmlparser/src/CNavDTD.cpp index 23561597ed4d..fcec3126bc0a 100644 --- a/parser/htmlparser/src/CNavDTD.cpp +++ b/parser/htmlparser/src/CNavDTD.cpp @@ -333,8 +333,7 @@ CNavDTD::~CNavDTD(){ delete mHeadContext; delete mBodyContext; - if(mTokenizer) - delete (nsHTMLTokenizer*)mTokenizer; + NS_IF_RELEASE(mTokenizer); if(mTempContext) delete mTempContext; @@ -3316,8 +3315,9 @@ nsITokenRecycler* CNavDTD::GetTokenRecycler(void){ * @return ptr to tokenizer */ nsITokenizer* CNavDTD::GetTokenizer(void) { - if(!mTokenizer) - mTokenizer=new nsHTMLTokenizer(mParseMode); + if(!mTokenizer) { + nsresult result=NS_NewHTMLTokenizer(&mTokenizer); + } return mTokenizer; } diff --git a/parser/htmlparser/src/nsExpatDTD.cpp b/parser/htmlparser/src/nsExpatDTD.cpp index d6a619a6bed2..1789039c794f 100644 --- a/parser/htmlparser/src/nsExpatDTD.cpp +++ b/parser/htmlparser/src/nsExpatDTD.cpp @@ -136,8 +136,7 @@ nsExpatDTD::nsExpatDTD() : nsIDTD(), mFilename("") { */ nsExpatDTD::~nsExpatDTD(){ mParser=0; //just to prove we destructed... - if(mTokenizer) - delete (nsExpatTokenizer*)mTokenizer; + NS_IF_RELEASE(mTokenizer); if (mExpatParser) XML_ParserFree(mExpatParser); } @@ -328,7 +327,7 @@ void nsExpatDTD::SetupExpatCallbacks(void) { */ nsITokenizer* nsExpatDTD::GetTokenizer(void) { if(!mTokenizer) { - mTokenizer=new nsExpatTokenizer(); + nsresult result=NS_New_Expat_Tokenizer(&mTokenizer); mExpatParser = XML_ParserCreate(NULL); if (mExpatParser) { SetupExpatCallbacks(); diff --git a/parser/htmlparser/src/nsExpatTokenizer.cpp b/parser/htmlparser/src/nsExpatTokenizer.cpp index 67f9ecd7f218..5cd3cdd8a6ee 100644 --- a/parser/htmlparser/src/nsExpatTokenizer.cpp +++ b/parser/htmlparser/src/nsExpatTokenizer.cpp @@ -58,6 +58,21 @@ static const char* kDocTypeDeclPrefix = "SetError(error); CToken* theToken = (CToken* )token; - AddToken(theToken, NS_OK, *gTokenDeque,gTokenRecycler); + AddToken(theToken, NS_OK, gTokenDeque,gTokenRecycler); } } @@ -290,6 +306,9 @@ nsresult nsExpatTokenizer::ParseXMLBuffer(const char* aBuffer, PRUint32 aLength, nsresult result=NS_OK; PR_ASSERT((aBuffer && aLength) || (aBuffer == nsnull && aLength == 0)); if (mExpatParser) { + + nsCOMPtr me=this; + if (!XML_Parse(mExpatParser, aBuffer, aLength, aIsFinal)) { PushXMLErrorToken(aBuffer, aLength, aIsFinal); result=NS_ERROR_HTMLPARSER_STOPPARSING; @@ -365,7 +384,7 @@ void nsExpatTokenizer::HandleStartElement(void *userData, const XML_Char *name, if(theToken) { nsString& theString=theToken->GetStringValueXXX(); theString.SetString((PRUnichar *) name); - AddToken(theToken,NS_OK,*gTokenDeque,gTokenRecycler); + AddToken(theToken,NS_OK,gTokenDeque,gTokenRecycler); int theAttrCount=0; while(*atts){ theAttrCount++; @@ -377,7 +396,7 @@ void nsExpatTokenizer::HandleStartElement(void *userData, const XML_Char *name, theValue.SetString((PRUnichar *) (*atts++)); } CToken* theTok=(CToken*)theAttrToken; - AddToken(theTok,NS_OK,*gTokenDeque,gTokenRecycler); + AddToken(theTok,NS_OK,gTokenDeque,gTokenRecycler); } theToken->SetAttributeCount(theAttrCount); } @@ -391,7 +410,7 @@ void nsExpatTokenizer::HandleEndElement(void *userData, const XML_Char *name) { if(theToken) { nsString& theString=theToken->GetStringValueXXX(); theString.SetString((PRUnichar *) name); - AddToken(theToken,NS_OK,*gTokenDeque,gTokenRecycler); + AddToken(theToken,NS_OK,gTokenDeque,gTokenRecycler); } else{ //THROW A HUGE ERROR IF WE CANT CREATE A TOKEN! @@ -425,7 +444,7 @@ void nsExpatTokenizer::HandleCharacterData(void *userData, const XML_Char *s, in nsString& theString=newToken->GetStringValueXXX(); theString.Append((PRUnichar *) s,len); } - AddToken(newToken,NS_OK,*gTokenDeque,gTokenRecycler); + AddToken(newToken,NS_OK,gTokenDeque,gTokenRecycler); } else { //THROW A HUGE ERROR IF WE CANT CREATE A TOKEN! @@ -438,7 +457,7 @@ void nsExpatTokenizer::HandleComment(void *userData, const XML_Char *name) { if(theToken) { nsString& theString=theToken->GetStringValueXXX(); theString.SetString((PRUnichar *) name); - AddToken(theToken,NS_OK,*gTokenDeque,gTokenRecycler); + AddToken(theToken,NS_OK,gTokenDeque,gTokenRecycler); } else{ //THROW A HUGE ERROR IF WE CANT CREATE A TOKEN! @@ -457,7 +476,7 @@ void nsExpatTokenizer::HandleEndCdataSection(void *userData) { // We've reached the end of the current CDATA section. Push the current // CDATA token onto the token queue - AddToken(currentCDataToken,NS_OK,*gTokenDeque,gTokenRecycler); + AddToken(currentCDataToken,NS_OK,gTokenDeque,gTokenRecycler); XML_SetUserData(gExpatParser, nsnull); } @@ -473,7 +492,7 @@ void nsExpatTokenizer::HandleProcessingInstruction(void *userData, const XML_Cha theString.Append((PRUnichar *) data); } theString.Append("?>"); - AddToken(theToken,NS_OK,*gTokenDeque,gTokenRecycler); + AddToken(theToken,NS_OK,gTokenDeque,gTokenRecycler); } else{ //THROW A HUGE ERROR IF WE CANT CREATE A TOKEN! @@ -487,7 +506,7 @@ void nsExpatTokenizer::HandleDefault(void *userData, const XML_Char *s, int len) while ((offset = str.FindChar('\n', PR_FALSE, offset + 1)) != -1) { newLine = gTokenRecycler->CreateTokenOfType(eToken_newline, eHTMLTag_unknown); - AddToken(newLine, NS_OK, *gTokenDeque, gTokenRecycler); + AddToken(newLine, NS_OK, gTokenDeque, gTokenRecycler); } } @@ -705,7 +724,7 @@ void nsExpatTokenizer::HandleStartDoctypeDecl(void *userData, str.Append(" "); str.Append((PRUnichar*) doctypeName); str.Append(">"); - AddToken(token,NS_OK,*gTokenDeque,gTokenRecycler); + AddToken(token,NS_OK,gTokenDeque,gTokenRecycler); } } diff --git a/parser/htmlparser/src/nsExpatTokenizer.h b/parser/htmlparser/src/nsExpatTokenizer.h index 2a12fa6141ad..78308d700ac4 100644 --- a/parser/htmlparser/src/nsExpatTokenizer.h +++ b/parser/htmlparser/src/nsExpatTokenizer.h @@ -42,6 +42,12 @@ {0x483836aa, 0xcabe, 0x11d2, { 0xab, 0xcb, 0x0, 0x10, 0x4b, 0x98, 0x3f, 0xd4 }} +// {575C063A-AE9C-11d3-B9FD-001083023C0E} +#define NS_EXPATTOKENIZER_CID \ +{ 0x575c063a, 0xae9c, 0x11d3, \ + {0xb9, 0xfd, 0x0, 0x10, 0x83, 0x2, 0x3c, 0xe}} + + /*************************************************************** Notes: ***************************************************************/ @@ -55,6 +61,9 @@ public: nsExpatTokenizer(nsString* aURL = nsnull); virtual ~nsExpatTokenizer(); + virtual const nsIID& GetCID(); + static const nsIID& GetIID(); + NS_DECL_ISUPPORTS /* nsITokenizer methods */ @@ -136,6 +145,6 @@ protected: nsString mLastLine; }; -extern NS_HTMLPARS nsresult NS_Expat_Tokenizer(nsIDTD** aInstancePtrResult); +extern NS_HTMLPARS nsresult NS_New_Expat_Tokenizer(nsITokenizer** aInstancePtrResult); #endif diff --git a/parser/htmlparser/src/nsHTMLTokenizer.cpp b/parser/htmlparser/src/nsHTMLTokenizer.cpp index dfc0558a044a..e81ec0230be2 100644 --- a/parser/htmlparser/src/nsHTMLTokenizer.cpp +++ b/parser/htmlparser/src/nsHTMLTokenizer.cpp @@ -85,20 +85,22 @@ nsHTMLTokenizer::FreeTokenRecycler(void) { } /** - * This method is defined in nsIParser. It is used to - * cause the COM-like construction of an nsParser. + * This method is defined in nsHTMLTokenizer.h. It is used to + * cause the COM-like construction of an HTMLTokenizer. * * @update gess 4/8/98 * @param nsIParser** ptr to newly instantiated parser * @return NS_xxx error result */ -NS_HTMLPARS nsresult NS_NewHTMLTokenizer(nsIDTD** aInstancePtrResult) { +NS_HTMLPARS nsresult NS_NewHTMLTokenizer(nsITokenizer** aInstancePtrResult) { + NS_PRECONDITION(nsnull != aInstancePtrResult, "null ptr"); + if (nsnull == aInstancePtrResult) { + return NS_ERROR_NULL_POINTER; + } nsHTMLTokenizer* it = new nsHTMLTokenizer(); - - if (it == 0) { + if (nsnull == it) { return NS_ERROR_OUT_OF_MEMORY; } - return it->QueryInterface(kClassIID, (void **) aInstancePtrResult); } @@ -142,10 +144,10 @@ nsHTMLTokenizer::~nsHTMLTokenizer(){ Here begins the real working methods for the tokenizer. *******************************************************************/ -void nsHTMLTokenizer::AddToken(CToken*& aToken,nsresult aResult,nsDeque& aDeque,CTokenRecycler* aRecycler) { - if(aToken) { +void nsHTMLTokenizer::AddToken(CToken*& aToken,nsresult aResult,nsDeque* aDeque,CTokenRecycler* aRecycler) { + if(aToken && aDeque) { if(NS_SUCCEEDED(aResult)) { - aDeque.Push(aToken); + aDeque->Push(aToken); } else { if(aRecycler) { @@ -423,7 +425,7 @@ nsresult nsHTMLTokenizer::ConsumeAttributes(PRUnichar aChar,CStartToken* aToken, } else { theAttrCount++; - AddToken(theToken,result,mTokenDeque,theRecycler); + AddToken(theToken,result,&mTokenDeque,theRecycler); } } else { //if(NS_ERROR_HTMLPARSER_BADATTRIBUTE==result){ @@ -447,7 +449,7 @@ nsresult nsHTMLTokenizer::ConsumeAttributes(PRUnichar aChar,CStartToken* aToken, eHTMLTags theEndTag = (eHTMLTags)aToken->GetTypeID(); if(result==NS_OK&&(gHTMLElements[theEndTag].mSkipTarget)){ CToken* theEndToken=theRecycler->CreateTokenOfType(eToken_end,theEndTag); - AddToken(theEndToken,NS_OK,mTokenDeque,theRecycler); + AddToken(theEndToken,NS_OK,&mTokenDeque,theRecycler); } done=PR_TRUE; } @@ -490,7 +492,7 @@ nsresult nsHTMLTokenizer::ConsumeStartTag(PRUnichar aChar,CToken*& aToken,nsScan result= aToken->Consume(aChar,aScanner,mParseMode); //tell new token to finish consuming text... if(NS_SUCCEEDED(result)) { - AddToken(aToken,result,mTokenDeque,theRecycler); + AddToken(aToken,result,&mTokenDeque,theRecycler); eHTMLTags theTag=(eHTMLTags)aToken->GetTypeID(); if(((CStartToken*)aToken)->IsAttributed()) { @@ -512,8 +514,8 @@ nsresult nsHTMLTokenizer::ConsumeStartTag(PRUnichar aChar,CToken*& aToken,nsScan result=((CTextToken*)textToken)->ConsumeUntil(0,PR_TRUE,aScanner,endTag,mParseMode); //tell new token to finish consuming text... //endTag.Append(">"); CToken* endToken=theRecycler->CreateTokenOfType(eToken_end,theTag,endTag); - AddToken(textToken,result,mTokenDeque,theRecycler); - AddToken(endToken,result,mTokenDeque,theRecycler); + AddToken(textToken,result,&mTokenDeque,theRecycler); + AddToken(endToken,result,&mTokenDeque,theRecycler); } } @@ -548,7 +550,7 @@ nsresult nsHTMLTokenizer::ConsumeEndTag(PRUnichar aChar,CToken*& aToken,nsScanne if(aToken) { result= aToken->Consume(aChar,aScanner,mParseMode); //tell new token to finish consuming text... - AddToken(aToken,result,mTokenDeque,theRecycler); + AddToken(aToken,result,&mTokenDeque,theRecycler); } //if return result; } @@ -594,7 +596,7 @@ nsresult nsHTMLTokenizer::ConsumeEntity(PRUnichar aChar,CToken*& aToken,nsScanne theRecycler->RecycleToken(aToken); aToken=theToken; } - AddToken(aToken,result,mTokenDeque,theRecycler); + AddToken(aToken,result,&mTokenDeque,theRecycler); } }//if return result; @@ -617,7 +619,7 @@ nsresult nsHTMLTokenizer::ConsumeWhitespace(PRUnichar aChar,CToken*& aToken,nsSc nsresult result=NS_OK; if(aToken) { result=aToken->Consume(aChar,aScanner,mParseMode); - AddToken(aToken,result,mTokenDeque,theRecycler); + AddToken(aToken,result,&mTokenDeque,theRecycler); } return result; } @@ -638,7 +640,7 @@ nsresult nsHTMLTokenizer::ConsumeComment(PRUnichar aChar,CToken*& aToken,nsScann nsresult result=NS_OK; if(aToken) { result=aToken->Consume(aChar,aScanner,mParseMode); - AddToken(aToken,result,mTokenDeque,theRecycler); + AddToken(aToken,result,&mTokenDeque,theRecycler); } return result; } @@ -668,7 +670,7 @@ nsresult nsHTMLTokenizer::ConsumeText(const nsString& aString,CToken*& aToken,ns } else result=NS_OK; } - AddToken(aToken,result,mTokenDeque,theRecycler); + AddToken(aToken,result,&mTokenDeque,theRecycler); } return result; } @@ -703,7 +705,7 @@ nsresult nsHTMLTokenizer::ConsumeSpecialMarkup(PRUnichar aChar,CToken*& aToken,n if(aToken) { result=aToken->Consume(aChar,aScanner,mParseMode); - AddToken(aToken,result,mTokenDeque,theRecycler); + AddToken(aToken,result,&mTokenDeque,theRecycler); } return result; } @@ -723,7 +725,7 @@ nsresult nsHTMLTokenizer::ConsumeNewline(PRUnichar aChar,CToken*& aToken,nsScann nsresult result=NS_OK; if(aToken) { result=aToken->Consume(aChar,aScanner,mParseMode); - AddToken(aToken,result,mTokenDeque,theRecycler); + AddToken(aToken,result,&mTokenDeque,theRecycler); } return result; } @@ -744,7 +746,7 @@ nsresult nsHTMLTokenizer::ConsumeProcessingInstruction(PRUnichar aChar,CToken*& nsresult result=NS_OK; if(aToken) { result=aToken->Consume(aChar,aScanner,mParseMode); - AddToken(aToken,result,mTokenDeque,theRecycler); + AddToken(aToken,result,&mTokenDeque,theRecycler); } return result; } diff --git a/parser/htmlparser/src/nsHTMLTokenizer.h b/parser/htmlparser/src/nsHTMLTokenizer.h index bee7ff772cdc..4b88ab470c4e 100644 --- a/parser/htmlparser/src/nsHTMLTokenizer.h +++ b/parser/htmlparser/src/nsHTMLTokenizer.h @@ -91,7 +91,7 @@ protected: virtual void RecordTrailingContent(CStartToken* aStartToken,nsScanner& aScanner); - static void AddToken(CToken*& aToken,nsresult aResult,nsDeque& aDeque,CTokenRecycler* aRecycler); + static void AddToken(CToken*& aToken,nsresult aResult,nsDeque* aDeque,CTokenRecycler* aRecycler); nsDeque mTokenDeque; PRBool mDoXMLEmptyTags; @@ -99,7 +99,7 @@ protected: PRBool mPlainText; }; -extern NS_HTMLPARS nsresult NS_NewHTMLTokenizer(nsIDTD** aInstancePtrResult); +extern NS_HTMLPARS nsresult NS_NewHTMLTokenizer(nsITokenizer** aInstancePtrResult); #endif diff --git a/parser/htmlparser/src/nsViewSourceHTML.cpp b/parser/htmlparser/src/nsViewSourceHTML.cpp index a53fffc72464..b38d05b0ac10 100644 --- a/parser/htmlparser/src/nsViewSourceHTML.cpp +++ b/parser/htmlparser/src/nsViewSourceHTML.cpp @@ -234,6 +234,9 @@ CViewSourceHTML::CViewSourceHTML() : nsIDTD(), */ CViewSourceHTML::~CViewSourceHTML(){ mParser=0; //just to prove we destructed... + + NS_IF_RELEASE(mTokenizer); + } /** @@ -448,8 +451,7 @@ nsITokenRecycler* CViewSourceHTML::GetTokenRecycler(void){ * @param * @return */ -nsresult CViewSourceHTML::Terminate(void) -{ +nsresult CViewSourceHTML::Terminate(void) { return NS_ERROR_HTMLPARSER_STOPPARSING; } @@ -461,7 +463,7 @@ nsresult CViewSourceHTML::Terminate(void) */ nsITokenizer* CViewSourceHTML::GetTokenizer(void) { if(!mTokenizer) { - mTokenizer = new nsHTMLTokenizer(eParseMode_quirks,mIsText); + nsresult result=NS_NewHTMLTokenizer(&mTokenizer); } return mTokenizer; } diff --git a/parser/htmlparser/src/nsWellFormedDTD.cpp b/parser/htmlparser/src/nsWellFormedDTD.cpp index 30063b3fbba2..bdb3c98c3ada 100644 --- a/parser/htmlparser/src/nsWellFormedDTD.cpp +++ b/parser/htmlparser/src/nsWellFormedDTD.cpp @@ -143,9 +143,7 @@ CWellFormedDTD::CWellFormedDTD() : nsIDTD(), mFilename("") { */ CWellFormedDTD::~CWellFormedDTD(){ mParser=0; //just to prove we destructed... - if (mTokenizer) - delete mTokenizer; - mTokenizer=0; + NS_IF_RELEASE(mTokenizer); } /** @@ -350,8 +348,10 @@ nsresult CWellFormedDTD::Terminate(void) * @return ptr to tokenizer */ nsITokenizer* CWellFormedDTD::GetTokenizer(void) { - if(!mTokenizer) + if(!mTokenizer) { mTokenizer=(nsHTMLTokenizer*)new nsExpatTokenizer(&mFilename); + NS_IF_ADDREF(mTokenizer); + } return mTokenizer; } diff --git a/parser/htmlparser/src/nsXIFDTD.cpp b/parser/htmlparser/src/nsXIFDTD.cpp index 10222cf66cc9..4e1c759dca19 100644 --- a/parser/htmlparser/src/nsXIFDTD.cpp +++ b/parser/htmlparser/src/nsXIFDTD.cpp @@ -264,6 +264,7 @@ nsXIFDTD::nsXIFDTD() : nsIDTD(){ */ nsXIFDTD::~nsXIFDTD(){ NS_IF_RELEASE(mSink); + NS_IF_RELEASE(mTokenizer); } @@ -1223,11 +1224,13 @@ nsresult nsXIFDTD::AddLeaf(const nsIParserNode& aNode) * @return */ nsITokenizer* nsXIFDTD::GetTokenizer(void){ - if(!mTokenizer) - mTokenizer=new nsXMLTokenizer(); + if(!mTokenizer) { + nsresult result=NS_NewXMLTokenizer(&mTokenizer); + } return mTokenizer; } + /** * * @update gess8/4/98 diff --git a/parser/htmlparser/src/nsXMLTokenizer.cpp b/parser/htmlparser/src/nsXMLTokenizer.cpp index 72ee27c7218a..28ed5c45a09c 100644 --- a/parser/htmlparser/src/nsXMLTokenizer.cpp +++ b/parser/htmlparser/src/nsXMLTokenizer.cpp @@ -91,7 +91,7 @@ nsXMLTokenizer::FreeTokenRecycler(void) { * @param nsIParser** ptr to newly instantiated parser * @return NS_xxx error result */ -NS_HTMLPARS nsresult NS_NewXMLTokenizer(nsIDTD** aInstancePtrResult) { +NS_HTMLPARS nsresult NS_NewXMLTokenizer(nsITokenizer** aInstancePtrResult){ nsXMLTokenizer* it = new nsXMLTokenizer(); if (it == 0) { @@ -208,7 +208,7 @@ nsresult nsXMLTokenizer::ConsumeComment(PRUnichar aChar,CToken*& aToken,nsScanne aToken=theRecycler->CreateTokenOfType(eToken_comment,eHTMLTag_comment,theEmpty); if(aToken) { result=aToken->Consume(aChar,aScanner,eParseMode_noquirks); - AddToken(aToken,result,mTokenDeque,theRecycler); + AddToken(aToken,result,&mTokenDeque,theRecycler); } } @@ -251,7 +251,7 @@ nsresult nsXMLTokenizer::ConsumeSpecialMarkup(PRUnichar aChar,CToken*& aToken,ns if(aToken) { result=aToken->Consume(aChar,aScanner,eParseMode_noquirks); - AddToken(aToken,result,mTokenDeque,theRecycler); + AddToken(aToken,result,&mTokenDeque,theRecycler); } } return result; diff --git a/parser/htmlparser/src/nsXMLTokenizer.h b/parser/htmlparser/src/nsXMLTokenizer.h index 6c198af6b0dc..0ce0486db8a3 100644 --- a/parser/htmlparser/src/nsXMLTokenizer.h +++ b/parser/htmlparser/src/nsXMLTokenizer.h @@ -72,7 +72,7 @@ protected: }; -extern NS_HTMLPARS nsresult NS_NewXMLTokenizer(nsIDTD** aInstancePtrResult); +extern NS_HTMLPARS nsresult NS_NewXMLTokenizer(nsITokenizer** aInstancePtrResult); #endif