From 2bad60b783dd7ca1f2158ad2f0b8a5181b6fd661 Mon Sep 17 00:00:00 2001 From: "rickg%netscape.com" Date: Wed, 11 Oct 2000 23:42:00 +0000 Subject: [PATCH] fixed RTM++ compatibility bugs: 53011, 54117, 54651, 54834, 54840, 55095. sr=buster, r=buster, attinasi, harish, sfraser for various portions. git-svn-id: svn://10.0.0.236/trunk@80977 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/htmlparser/src/CNavDTD.cpp | 48 +++++--- mozilla/htmlparser/src/nsElementTable.cpp | 22 +++- mozilla/htmlparser/src/nsElementTable.h | 1 + mozilla/htmlparser/src/nsHTMLTokenizer.cpp | 105 +++++++++--------- mozilla/htmlparser/src/nsHTMLTokens.cpp | 4 + mozilla/htmlparser/src/nsIHTMLContentSink.h | 6 +- mozilla/parser/htmlparser/src/CNavDTD.cpp | 48 +++++--- .../parser/htmlparser/src/nsElementTable.cpp | 22 +++- .../parser/htmlparser/src/nsElementTable.h | 1 + .../parser/htmlparser/src/nsHTMLTokenizer.cpp | 105 +++++++++--------- .../parser/htmlparser/src/nsHTMLTokens.cpp | 4 + .../htmlparser/src/nsIHTMLContentSink.h | 6 +- 12 files changed, 234 insertions(+), 138 deletions(-) diff --git a/mozilla/htmlparser/src/CNavDTD.cpp b/mozilla/htmlparser/src/CNavDTD.cpp index 8782e8ca9ae..183b7e0bf05 100644 --- a/mozilla/htmlparser/src/CNavDTD.cpp +++ b/mozilla/htmlparser/src/CNavDTD.cpp @@ -843,7 +843,7 @@ nsresult CNavDTD::DidHandleStartTag(nsCParserNode& aNode,eHTMLTags aChildTag){ case eHTMLTag_counter: { PRInt32 theCount=mBodyContext->GetCount(); - eHTMLTags theGrandParentTag=mBodyContext->TagAt(theCount-2); + eHTMLTags theGrandParentTag=mBodyContext->TagAt(theCount-1); nsAutoString theNumber; @@ -980,23 +980,47 @@ PRBool CanBeContained(eHTMLTags aChildTag,nsDTDContext& aContext) { //Note: This method is going away. First we need to get the elementtable to do closures right, and // therefore we must get residual style handling to work. - PRBool result=PR_TRUE; - if(aContext.GetCount()){ + //the changes to this method were added to fix bug 54651... + + PRBool result=PR_TRUE; + PRInt32 theCount=aContext.GetCount(); + + if(0theSPIndex) ? theRootIndex : theSPIndex; + PRInt32 theTargetIndex=(theRootIndex>theSPIndex) ? theRootIndex : theSPIndex; - if((theBaseIndex==theChildIndex) && (gHTMLElements[aChildTag].CanContainSelf())) + if((theTargetIndex==theCount-1) || + ((theTargetIndex==theChildIndex) && gHTMLElements[aChildTag].CanContainSelf())) { result=PR_TRUE; - else result=PRBool(theBaseIndex>theChildIndex); + } + else { + + result=PR_FALSE; + + PRInt32 theIndex=theCount-1; + while(theChildIndexPeekNode()); if(theParentNode->mToken->IsWellFormed()) { theRule=eLetInlineContainBlock; @@ -1189,15 +1213,12 @@ nsresult CNavDTD::WillHandleStartTag(CToken* aToken,eHTMLTags aTag,nsCParserNode /************************************************************************************** * * Now a little code to deal with bug #49687 (crash when layout stack gets too deep) + * I've also opened this up to any container (not just inlines): re bug 55095 * **************************************************************************************/ if(MAX_REFLOW_DEPTHGetCount()) { - if(gHTMLElements[aTag].IsMemberOf(kInlineEntity)) { - if(!gHTMLElements[aTag].IsMemberOf(kFormControl)) { - return kHierarchyTooDeep; - } - } + return kHierarchyTooDeep; } STOP_TIMER() @@ -1640,7 +1661,8 @@ eHTMLTags FindAutoCloseTargetForEndTag(eHTMLTags aCurrentTag,nsDTDContext& aCont PRInt32 theChildIndex=GetIndexOfChildOrSynonym(aContext,aCurrentTag); if(kNotFound=anIndex) && (eHTMLTag_unknown==result)){ eHTMLTags theTag=aContext.TagAt(theIndex); diff --git a/mozilla/htmlparser/src/nsElementTable.h b/mozilla/htmlparser/src/nsElementTable.h index 853ae47a00e..492a75db3fb 100644 --- a/mozilla/htmlparser/src/nsElementTable.h +++ b/mozilla/htmlparser/src/nsElementTable.h @@ -161,6 +161,7 @@ struct nsHTMLElement { TagList* GetSpecialParents(void) const {return mSpecialParents;} PRBool IsMemberOf(PRInt32 aType) const; + PRBool ContainsSet(PRInt32 aType) const; PRBool CanContainType(PRInt32 aType) const; eHTMLTags GetTag(void) const {return mTagID;} diff --git a/mozilla/htmlparser/src/nsHTMLTokenizer.cpp b/mozilla/htmlparser/src/nsHTMLTokenizer.cpp index 21f285b167b..bae9930fa16 100644 --- a/mozilla/htmlparser/src/nsHTMLTokenizer.cpp +++ b/mozilla/htmlparser/src/nsHTMLTokenizer.cpp @@ -343,69 +343,74 @@ nsresult nsHTMLTokenizer::ScanDocStructure(PRBool aFinalChunk) { eHTMLTokenTypes theType=eHTMLTokenTypes(theToken->GetTokenType()); eHTMLTags theTag=(eHTMLTags)theToken->GetTypeID(); - PRBool theTagIsBlock=gHTMLElements[theTag].IsMemberOf(kBlockEntity); - PRBool theTagIsInline= (theTagIsBlock) ? PR_FALSE : gHTMLElements[theTag].IsMemberOf(kInlineEntity); - if(theTagIsBlock || theTagIsInline || (eHTMLTag_table==theTag)) { + PRBool theTagIsContainer=nsHTMLElement::IsContainer(theTag); //bug54117... - switch(theType) { + if(theTagIsContainer) { + PRBool theTagIsBlock=gHTMLElements[theTag].IsMemberOf(kBlockEntity); + PRBool theTagIsInline= (theTagIsBlock) ? PR_FALSE : gHTMLElements[theTag].IsMemberOf(kInlineEntity); - case eToken_start: - if(0==theStack.GetSize()) { - //track the tag on the top of the stack... - theRootToken=theToken; - theRootTag=theTag; - } - theStack.Push(theToken); - theStackDepth++; - break; + if(theTagIsBlock || theTagIsInline || (eHTMLTag_table==theTag)) { - case eToken_end: - { - CHTMLToken *theLastToken= NS_STATIC_CAST(CHTMLToken*, theStack.Peek()); - if(theLastToken) { - if(theTag==theLastToken->GetTypeID()) { - theStack.Pop(); //yank it for real - theStackDepth--; - theLastToken->SetContainerInfo(eWellFormed); + switch(theType) { - //in addition, let's look above this container to see if we can find - //any tags that are already marked malformed. If so, pop them too! + case eToken_start: + if(0==theStack.GetSize()) { + //track the tag on the top of the stack... + theRootToken=theToken; + theRootTag=theTag; + } + theStack.Push(theToken); + theStackDepth++; + break; - theLastToken= NS_STATIC_CAST(CHTMLToken*, theStack.Peek()); - while(theLastToken) { - if(eMalformed==theRootToken->GetContainerInfo()) { - theStack.Pop(); //yank the malformed token for real. - theLastToken= NS_STATIC_CAST(CHTMLToken*, theStack.Peek()); - continue; + case eToken_end: + { + CHTMLToken *theLastToken= NS_STATIC_CAST(CHTMLToken*, theStack.Peek()); + if(theLastToken) { + if(theTag==theLastToken->GetTypeID()) { + theStack.Pop(); //yank it for real + theStackDepth--; + theLastToken->SetContainerInfo(eWellFormed); + + //in addition, let's look above this container to see if we can find + //any tags that are already marked malformed. If so, pop them too! + + theLastToken= NS_STATIC_CAST(CHTMLToken*, theStack.Peek()); + while(theLastToken) { + if(eMalformed==theRootToken->GetContainerInfo()) { + theStack.Pop(); //yank the malformed token for real. + theLastToken= NS_STATIC_CAST(CHTMLToken*, theStack.Peek()); + continue; + } + break; } - break; - } - } - else { - //the topmost token isn't what we expected, so that container must - //be malformed. If the tag is a block, we don't really care (but we'll - //mark it anyway). If it's an inline we DO care, especially if the - //inline tried to contain a block (that's when RS handling kicks in). - if(theTagIsInline) { - PRInt32 theIndex=FindLastIndexOfTag(theTag,theStack); - if(kNotFound!=theIndex) { - theToken=(CHTMLToken*)theStack.ObjectAt(theIndex); - theToken->SetContainerInfo(eMalformed); - } - //otherwise we ignore an out-of-place end tag. } else { + //the topmost token isn't what we expected, so that container must + //be malformed. If the tag is a block, we don't really care (but we'll + //mark it anyway). If it's an inline we DO care, especially if the + //inline tried to contain a block (that's when RS handling kicks in). + if(theTagIsInline) { + PRInt32 theIndex=FindLastIndexOfTag(theTag,theStack); + if(kNotFound!=theIndex) { + theToken=(CHTMLToken*)theStack.ObjectAt(theIndex); + theToken->SetContainerInfo(eMalformed); + } + //otherwise we ignore an out-of-place end tag. + } + else { + } } } - } - } - break; + } + break; - default: - break; - } //switch + default: + break; + } //switch + } } theToken=(CHTMLToken*)mTokenDeque.ObjectAt(++mTokenScanPos); diff --git a/mozilla/htmlparser/src/nsHTMLTokens.cpp b/mozilla/htmlparser/src/nsHTMLTokens.cpp index 5b7d75a5944..da10666a711 100644 --- a/mozilla/htmlparser/src/nsHTMLTokens.cpp +++ b/mozilla/htmlparser/src/nsHTMLTokens.cpp @@ -997,9 +997,13 @@ nsresult CCommentToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 aMo nsresult result=PR_TRUE; switch(aMode) { + +#if 0 //set to 1 if you want strict comments... bug 53011... case eDTDMode_strict: result=ConsumeStrictComment(aChar,aScanner,mTextValue); break; +#endif + case eDTDMode_transitional: default: result=ConsumeComment(aChar,aScanner,mTextValue); diff --git a/mozilla/htmlparser/src/nsIHTMLContentSink.h b/mozilla/htmlparser/src/nsIHTMLContentSink.h index 7f1f8efbd13..061733bb9d2 100644 --- a/mozilla/htmlparser/src/nsIHTMLContentSink.h +++ b/mozilla/htmlparser/src/nsIHTMLContentSink.h @@ -73,7 +73,11 @@ { 0xa6cf9051, 0x15b3, 0x11d2,{0x93, 0x2e, 0x00, 0x80, 0x5f, 0x8a, 0xdd, 0x32}} -#define MAX_REFLOW_DEPTH 200 +#ifdef XP_MAC +#define MAX_REFLOW_DEPTH 75 //setting to 75 to prevent layout from crashing on mac. Bug 55095. +#else +#define MAX_REFLOW_DEPTH 200 //windows and linux (etc) can do much deeper structures. +#endif class nsIHTMLContentSink : public nsIContentSink { diff --git a/mozilla/parser/htmlparser/src/CNavDTD.cpp b/mozilla/parser/htmlparser/src/CNavDTD.cpp index 8782e8ca9ae..183b7e0bf05 100644 --- a/mozilla/parser/htmlparser/src/CNavDTD.cpp +++ b/mozilla/parser/htmlparser/src/CNavDTD.cpp @@ -843,7 +843,7 @@ nsresult CNavDTD::DidHandleStartTag(nsCParserNode& aNode,eHTMLTags aChildTag){ case eHTMLTag_counter: { PRInt32 theCount=mBodyContext->GetCount(); - eHTMLTags theGrandParentTag=mBodyContext->TagAt(theCount-2); + eHTMLTags theGrandParentTag=mBodyContext->TagAt(theCount-1); nsAutoString theNumber; @@ -980,23 +980,47 @@ PRBool CanBeContained(eHTMLTags aChildTag,nsDTDContext& aContext) { //Note: This method is going away. First we need to get the elementtable to do closures right, and // therefore we must get residual style handling to work. - PRBool result=PR_TRUE; - if(aContext.GetCount()){ + //the changes to this method were added to fix bug 54651... + + PRBool result=PR_TRUE; + PRInt32 theCount=aContext.GetCount(); + + if(0theSPIndex) ? theRootIndex : theSPIndex; + PRInt32 theTargetIndex=(theRootIndex>theSPIndex) ? theRootIndex : theSPIndex; - if((theBaseIndex==theChildIndex) && (gHTMLElements[aChildTag].CanContainSelf())) + if((theTargetIndex==theCount-1) || + ((theTargetIndex==theChildIndex) && gHTMLElements[aChildTag].CanContainSelf())) { result=PR_TRUE; - else result=PRBool(theBaseIndex>theChildIndex); + } + else { + + result=PR_FALSE; + + PRInt32 theIndex=theCount-1; + while(theChildIndexPeekNode()); if(theParentNode->mToken->IsWellFormed()) { theRule=eLetInlineContainBlock; @@ -1189,15 +1213,12 @@ nsresult CNavDTD::WillHandleStartTag(CToken* aToken,eHTMLTags aTag,nsCParserNode /************************************************************************************** * * Now a little code to deal with bug #49687 (crash when layout stack gets too deep) + * I've also opened this up to any container (not just inlines): re bug 55095 * **************************************************************************************/ if(MAX_REFLOW_DEPTHGetCount()) { - if(gHTMLElements[aTag].IsMemberOf(kInlineEntity)) { - if(!gHTMLElements[aTag].IsMemberOf(kFormControl)) { - return kHierarchyTooDeep; - } - } + return kHierarchyTooDeep; } STOP_TIMER() @@ -1640,7 +1661,8 @@ eHTMLTags FindAutoCloseTargetForEndTag(eHTMLTags aCurrentTag,nsDTDContext& aCont PRInt32 theChildIndex=GetIndexOfChildOrSynonym(aContext,aCurrentTag); if(kNotFound=anIndex) && (eHTMLTag_unknown==result)){ eHTMLTags theTag=aContext.TagAt(theIndex); diff --git a/mozilla/parser/htmlparser/src/nsElementTable.h b/mozilla/parser/htmlparser/src/nsElementTable.h index 853ae47a00e..492a75db3fb 100644 --- a/mozilla/parser/htmlparser/src/nsElementTable.h +++ b/mozilla/parser/htmlparser/src/nsElementTable.h @@ -161,6 +161,7 @@ struct nsHTMLElement { TagList* GetSpecialParents(void) const {return mSpecialParents;} PRBool IsMemberOf(PRInt32 aType) const; + PRBool ContainsSet(PRInt32 aType) const; PRBool CanContainType(PRInt32 aType) const; eHTMLTags GetTag(void) const {return mTagID;} diff --git a/mozilla/parser/htmlparser/src/nsHTMLTokenizer.cpp b/mozilla/parser/htmlparser/src/nsHTMLTokenizer.cpp index 21f285b167b..bae9930fa16 100644 --- a/mozilla/parser/htmlparser/src/nsHTMLTokenizer.cpp +++ b/mozilla/parser/htmlparser/src/nsHTMLTokenizer.cpp @@ -343,69 +343,74 @@ nsresult nsHTMLTokenizer::ScanDocStructure(PRBool aFinalChunk) { eHTMLTokenTypes theType=eHTMLTokenTypes(theToken->GetTokenType()); eHTMLTags theTag=(eHTMLTags)theToken->GetTypeID(); - PRBool theTagIsBlock=gHTMLElements[theTag].IsMemberOf(kBlockEntity); - PRBool theTagIsInline= (theTagIsBlock) ? PR_FALSE : gHTMLElements[theTag].IsMemberOf(kInlineEntity); - if(theTagIsBlock || theTagIsInline || (eHTMLTag_table==theTag)) { + PRBool theTagIsContainer=nsHTMLElement::IsContainer(theTag); //bug54117... - switch(theType) { + if(theTagIsContainer) { + PRBool theTagIsBlock=gHTMLElements[theTag].IsMemberOf(kBlockEntity); + PRBool theTagIsInline= (theTagIsBlock) ? PR_FALSE : gHTMLElements[theTag].IsMemberOf(kInlineEntity); - case eToken_start: - if(0==theStack.GetSize()) { - //track the tag on the top of the stack... - theRootToken=theToken; - theRootTag=theTag; - } - theStack.Push(theToken); - theStackDepth++; - break; + if(theTagIsBlock || theTagIsInline || (eHTMLTag_table==theTag)) { - case eToken_end: - { - CHTMLToken *theLastToken= NS_STATIC_CAST(CHTMLToken*, theStack.Peek()); - if(theLastToken) { - if(theTag==theLastToken->GetTypeID()) { - theStack.Pop(); //yank it for real - theStackDepth--; - theLastToken->SetContainerInfo(eWellFormed); + switch(theType) { - //in addition, let's look above this container to see if we can find - //any tags that are already marked malformed. If so, pop them too! + case eToken_start: + if(0==theStack.GetSize()) { + //track the tag on the top of the stack... + theRootToken=theToken; + theRootTag=theTag; + } + theStack.Push(theToken); + theStackDepth++; + break; - theLastToken= NS_STATIC_CAST(CHTMLToken*, theStack.Peek()); - while(theLastToken) { - if(eMalformed==theRootToken->GetContainerInfo()) { - theStack.Pop(); //yank the malformed token for real. - theLastToken= NS_STATIC_CAST(CHTMLToken*, theStack.Peek()); - continue; + case eToken_end: + { + CHTMLToken *theLastToken= NS_STATIC_CAST(CHTMLToken*, theStack.Peek()); + if(theLastToken) { + if(theTag==theLastToken->GetTypeID()) { + theStack.Pop(); //yank it for real + theStackDepth--; + theLastToken->SetContainerInfo(eWellFormed); + + //in addition, let's look above this container to see if we can find + //any tags that are already marked malformed. If so, pop them too! + + theLastToken= NS_STATIC_CAST(CHTMLToken*, theStack.Peek()); + while(theLastToken) { + if(eMalformed==theRootToken->GetContainerInfo()) { + theStack.Pop(); //yank the malformed token for real. + theLastToken= NS_STATIC_CAST(CHTMLToken*, theStack.Peek()); + continue; + } + break; } - break; - } - } - else { - //the topmost token isn't what we expected, so that container must - //be malformed. If the tag is a block, we don't really care (but we'll - //mark it anyway). If it's an inline we DO care, especially if the - //inline tried to contain a block (that's when RS handling kicks in). - if(theTagIsInline) { - PRInt32 theIndex=FindLastIndexOfTag(theTag,theStack); - if(kNotFound!=theIndex) { - theToken=(CHTMLToken*)theStack.ObjectAt(theIndex); - theToken->SetContainerInfo(eMalformed); - } - //otherwise we ignore an out-of-place end tag. } else { + //the topmost token isn't what we expected, so that container must + //be malformed. If the tag is a block, we don't really care (but we'll + //mark it anyway). If it's an inline we DO care, especially if the + //inline tried to contain a block (that's when RS handling kicks in). + if(theTagIsInline) { + PRInt32 theIndex=FindLastIndexOfTag(theTag,theStack); + if(kNotFound!=theIndex) { + theToken=(CHTMLToken*)theStack.ObjectAt(theIndex); + theToken->SetContainerInfo(eMalformed); + } + //otherwise we ignore an out-of-place end tag. + } + else { + } } } - } - } - break; + } + break; - default: - break; - } //switch + default: + break; + } //switch + } } theToken=(CHTMLToken*)mTokenDeque.ObjectAt(++mTokenScanPos); diff --git a/mozilla/parser/htmlparser/src/nsHTMLTokens.cpp b/mozilla/parser/htmlparser/src/nsHTMLTokens.cpp index 5b7d75a5944..da10666a711 100644 --- a/mozilla/parser/htmlparser/src/nsHTMLTokens.cpp +++ b/mozilla/parser/htmlparser/src/nsHTMLTokens.cpp @@ -997,9 +997,13 @@ nsresult CCommentToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 aMo nsresult result=PR_TRUE; switch(aMode) { + +#if 0 //set to 1 if you want strict comments... bug 53011... case eDTDMode_strict: result=ConsumeStrictComment(aChar,aScanner,mTextValue); break; +#endif + case eDTDMode_transitional: default: result=ConsumeComment(aChar,aScanner,mTextValue); diff --git a/mozilla/parser/htmlparser/src/nsIHTMLContentSink.h b/mozilla/parser/htmlparser/src/nsIHTMLContentSink.h index 7f1f8efbd13..061733bb9d2 100644 --- a/mozilla/parser/htmlparser/src/nsIHTMLContentSink.h +++ b/mozilla/parser/htmlparser/src/nsIHTMLContentSink.h @@ -73,7 +73,11 @@ { 0xa6cf9051, 0x15b3, 0x11d2,{0x93, 0x2e, 0x00, 0x80, 0x5f, 0x8a, 0xdd, 0x32}} -#define MAX_REFLOW_DEPTH 200 +#ifdef XP_MAC +#define MAX_REFLOW_DEPTH 75 //setting to 75 to prevent layout from crashing on mac. Bug 55095. +#else +#define MAX_REFLOW_DEPTH 200 //windows and linux (etc) can do much deeper structures. +#endif class nsIHTMLContentSink : public nsIContentSink {