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.
This commit is contained in:
rickg%netscape.com 1999-12-10 04:01:26 +00:00
parent 81f434990e
commit 512157dd9d
22 changed files with 180 additions and 112 deletions

View File

@ -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;
}

View File

@ -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();

View File

@ -58,6 +58,21 @@ static const char* kDocTypeDeclPrefix = "<!DOCTYPE";
static const char* kChromeProtocol = "chrome";
static const char* kDTDDirectory = "dtd/";
const nsIID&
nsExpatTokenizer::GetIID()
{
return kClassIID;
}
const nsIID&
nsExpatTokenizer::GetCID()
{
static NS_DEFINE_IID(kCID, NS_EXPATTOKENIZER_CID);
return kCID;
}
/**
* This method gets called as part of our COM-like interfaces.
* Its purpose is to create an interface to parser object
@ -107,7 +122,7 @@ nsExpatTokenizer::FreeTokenRecycler(void) {
* @param nsIParser** ptr to newly instantiated parser
* @return NS_xxx error result
*/
NS_HTMLPARS nsresult NS_New_Expat_Tokenizer(nsIDTD** aInstancePtrResult) {
NS_HTMLPARS nsresult NS_New_Expat_Tokenizer(nsITokenizer** aInstancePtrResult) {
nsExpatTokenizer* it = new nsExpatTokenizer();
if (it == 0) {
return NS_ERROR_OUT_OF_MEMORY;
@ -182,6 +197,7 @@ nsExpatTokenizer::~nsExpatTokenizer(){
XML_ParserFree(mExpatParser);
mExpatParser = nsnull;
}
gTokenDeque=0;
}
@ -281,7 +297,7 @@ void nsExpatTokenizer::PushXMLErrorToken(const char *aBuffer, PRUint32 aLength,
token->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<nsExpatTokenizer> 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);
}
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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

View File

@ -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;

View File

@ -72,7 +72,7 @@ protected:
};
extern NS_HTMLPARS nsresult NS_NewXMLTokenizer(nsIDTD** aInstancePtrResult);
extern NS_HTMLPARS nsresult NS_NewXMLTokenizer(nsITokenizer** aInstancePtrResult);
#endif

View File

@ -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;
}

View File

@ -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();

View File

@ -58,6 +58,21 @@ static const char* kDocTypeDeclPrefix = "<!DOCTYPE";
static const char* kChromeProtocol = "chrome";
static const char* kDTDDirectory = "dtd/";
const nsIID&
nsExpatTokenizer::GetIID()
{
return kClassIID;
}
const nsIID&
nsExpatTokenizer::GetCID()
{
static NS_DEFINE_IID(kCID, NS_EXPATTOKENIZER_CID);
return kCID;
}
/**
* This method gets called as part of our COM-like interfaces.
* Its purpose is to create an interface to parser object
@ -107,7 +122,7 @@ nsExpatTokenizer::FreeTokenRecycler(void) {
* @param nsIParser** ptr to newly instantiated parser
* @return NS_xxx error result
*/
NS_HTMLPARS nsresult NS_New_Expat_Tokenizer(nsIDTD** aInstancePtrResult) {
NS_HTMLPARS nsresult NS_New_Expat_Tokenizer(nsITokenizer** aInstancePtrResult) {
nsExpatTokenizer* it = new nsExpatTokenizer();
if (it == 0) {
return NS_ERROR_OUT_OF_MEMORY;
@ -182,6 +197,7 @@ nsExpatTokenizer::~nsExpatTokenizer(){
XML_ParserFree(mExpatParser);
mExpatParser = nsnull;
}
gTokenDeque=0;
}
@ -281,7 +297,7 @@ void nsExpatTokenizer::PushXMLErrorToken(const char *aBuffer, PRUint32 aLength,
token->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<nsExpatTokenizer> 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);
}
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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

View File

@ -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;

View File

@ -72,7 +72,7 @@ protected:
};
extern NS_HTMLPARS nsresult NS_NewXMLTokenizer(nsIDTD** aInstancePtrResult);
extern NS_HTMLPARS nsresult NS_NewXMLTokenizer(nsITokenizer** aInstancePtrResult);
#endif