bug 70918: view-source adds > to tags that are missing them. r=bzbarsky sr=dmose

This commit is contained in:
mrbkap%gmail.com 2004-10-17 03:03:46 +00:00
Родитель cc085ad3d0
Коммит 36c54fb6da
6 изменённых файлов: 67 добавлений и 31 удалений

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

@ -264,6 +264,16 @@ class CToken {
mLineNumber = mLineNumber == 0 ? aLineNumber : mLineNumber; mLineNumber = mLineNumber == 0 ? aLineNumber : mLineNumber;
} }
void SetInError(PRBool aInError)
{
mInError = aInError;
}
PRBool IsInError()
{
return mInError;
}
void SetAttributeCount(PRInt16 aValue) { mAttrCount = aValue; } void SetAttributeCount(PRInt16 aValue) { mAttrCount = aValue; }
/** /**
@ -285,7 +295,8 @@ protected:
PRInt32 mTypeID; PRInt32 mTypeID;
PRInt32 mUseCount; PRInt32 mUseCount;
PRInt32 mNewlineCount; PRInt32 mNewlineCount;
PRInt32 mLineNumber; PRUint32 mLineNumber : 31;
PRUint32 mInError : 1;
PRInt16 mAttrCount; PRInt16 mAttrCount;
}; };

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

@ -688,12 +688,17 @@ nsresult nsHTMLTokenizer::ConsumeAttributes(PRUnichar aChar,
done = PR_TRUE; done = PR_TRUE;
} }
else if(aChar == kLessThan) { else if(aChar == kLessThan) {
aToken->SetInError(PR_TRUE);
done = PR_TRUE; done = PR_TRUE;
} }
}//if }//if
}//if }//if
}//while }//while
if (NS_FAILED(result)) {
aToken->SetInError(PR_TRUE);
}
aToken->SetAttributeCount(theAttrCount); aToken->SetAttributeCount(theAttrCount);
return result; return result;
} }
@ -728,6 +733,9 @@ nsresult nsHTMLTokenizer::ConsumeStartTag(PRUnichar aChar,CToken*& aToken,nsScan
//Good. Now, let's see if the next char is ">". //Good. Now, let's see if the next char is ">".
//If so, we have a complete tag, otherwise, we have attributes. //If so, we have a complete tag, otherwise, we have attributes.
result = aScanner.Peek(aChar); result = aScanner.Peek(aChar);
if (NS_FAILED(result)) {
aToken->SetInError(PR_TRUE);
}
NS_ENSURE_SUCCESS(result, result); NS_ENSURE_SUCCESS(result, result);
if(kGreaterThan != aChar) { //look for '>' if(kGreaterThan != aChar) { //look for '>'
@ -854,6 +862,9 @@ nsresult nsHTMLTokenizer::ConsumeEndTag(PRUnichar aChar,CToken*& aToken,nsScanne
NS_ENSURE_SUCCESS(result, result); NS_ENSURE_SUCCESS(result, result);
result = aScanner.Peek(aChar); result = aScanner.Peek(aChar);
if (NS_FAILED(result)) {
aToken->SetInError(PR_TRUE);
}
NS_ENSURE_SUCCESS(result, result); NS_ENSURE_SUCCESS(result, result);
if(kGreaterThan != aChar) { if(kGreaterThan != aChar) {

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

@ -746,11 +746,6 @@ nsresult CCDATASectionToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt3
if (NS_OK==result && if (NS_OK==result &&
(!inCDATA || kGreaterThan == aChar)) { (!inCDATA || kGreaterThan == aChar)) {
result=aScanner.GetChar(aChar); //strip off the > result=aScanner.GetChar(aChar); //strip off the >
// XXX take me out when view source isn't stupid anymore
if (aFlag & NS_IPARSER_FLAG_VIEW_SOURCE) {
mTextValue.Append(aChar);
}
done=PR_TRUE; done=PR_TRUE;
} }
} }
@ -763,8 +758,7 @@ nsresult CCDATASectionToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt3
// In order to not completely lose the entire section, treat everything // In order to not completely lose the entire section, treat everything
// until the end of the document as part of the CDATA section and let // until the end of the document as part of the CDATA section and let
// the DTD handle it. // the DTD handle it.
// XXX when view source actually displays errors, we'll need to propagate mInError = PR_TRUE;
// the EOF down to it (i.e., not do this if we're viewing source).
result = NS_OK; result = NS_OK;
} }
@ -896,6 +890,14 @@ nsresult CMarkupDeclToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32
aScanner.BindSubstring(mTextValue, origin, end); aScanner.BindSubstring(mTextValue, origin, end);
if (kEOF == result) {
mInError = PR_TRUE;
if (!aScanner.IsIncremental()) {
// Hide this EOF.
result = NS_OK;
}
}
return result; return result;
} }
@ -1732,6 +1734,7 @@ nsresult CAttributeToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 a
mTextValue.Append(aChar); mTextValue.Append(aChar);
} else if (result == NS_ERROR_HTMLPARSER_UNTERMINATEDSTRINGLITERAL) { } else if (result == NS_ERROR_HTMLPARSER_UNTERMINATEDSTRINGLITERAL) {
result = NS_OK; result = NS_OK;
mInError = PR_TRUE;
} }
// According to spec. we ( who? ) should ignore linefeeds. But look, // According to spec. we ( who? ) should ignore linefeeds. But look,
// even the carriage return was getting stripped ( wonder why! ) - // even the carriage return was getting stripped ( wonder why! ) -
@ -1744,6 +1747,7 @@ nsresult CAttributeToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 a
} }
else if (kGreaterThan==aChar){ else if (kGreaterThan==aChar){
mHasEqualWithoutValue=PR_TRUE; mHasEqualWithoutValue=PR_TRUE;
mInError=PR_TRUE;
} }
else { else {
static const nsReadEndCondition static const nsReadEndCondition
@ -1777,6 +1781,7 @@ nsresult CAttributeToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 a
//so let's see what it is. If it's a '"', then assume we're reading //so let's see what it is. If it's a '"', then assume we're reading
//from the middle of the value. Try stripping the quote and continuing... //from the middle of the value. Try stripping the quote and continuing...
if (kQuote==aChar || kApostrophe==aChar){ if (kQuote==aChar || kApostrophe==aChar){
mInError=PR_TRUE;
if (!(aFlag & NS_IPARSER_FLAG_VIEW_SOURCE)) { if (!(aFlag & NS_IPARSER_FLAG_VIEW_SOURCE)) {
result=aScanner.SkipOver(aChar); //strip quote. result=aScanner.SkipOver(aChar); //strip quote.
@ -2244,6 +2249,7 @@ nsresult CInstructionToken::Consume(PRUnichar aChar,nsScanner& aScanner,PRInt32
if (kEOF==result && !aScanner.IsIncremental()) { if (kEOF==result && !aScanner.IsIncremental()) {
//Hide the EOF result because there is no more text coming. //Hide the EOF result because there is no more text coming.
mInError=PR_TRUE;
result=NS_OK; result=NS_OK;
} }
@ -2307,12 +2313,17 @@ nsresult CDoctypeDeclToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32
// could belong to another tag. // could belong to another tag.
aScanner.GetChar(ch); aScanner.GetChar(ch);
end.advance(1); end.advance(1);
} else {
NS_ASSERTION(kLessThan == ch,
"Make sure this doctype decl. is really in error.");
mInError = PR_TRUE;
} }
} }
else if (!aScanner.IsIncremental()) { else if (!aScanner.IsIncremental()) {
// We have reached the document end but haven't // We have reached the document end but haven't
// found either a '<' or a '>'. Therefore use // found either a '<' or a '>'. Therefore use
// whatever we have. // whatever we have.
mInError = PR_TRUE;
result = NS_OK; result = NS_OK;
} }

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

@ -69,6 +69,7 @@ CToken::CToken(PRInt32 aTag) {
mAttrCount=0; mAttrCount=0;
mNewlineCount=0; mNewlineCount=0;
mLineNumber = 0; mLineNumber = 0;
mInError = PR_FALSE;
mTypeID=aTag; mTypeID=aTag;
// Note that the use count starts with 1 instead of 0. This // Note that the use count starts with 1 instead of 0. This
// is because of the assumption that any token created is in // is because of the assumption that any token created is in

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

@ -978,7 +978,7 @@ nsresult CViewSourceHTML::WriteAttributes(PRInt32 attrCount) {
* @param * @param
* @return result status * @return result status
*/ */
nsresult CViewSourceHTML::WriteTag(PRInt32 aTagType,const nsAString & aText,PRInt32 attrCount,PRBool aNewlineRequired) { nsresult CViewSourceHTML::WriteTag(PRInt32 aTagType,const nsAString & aText,PRInt32 attrCount,PRBool aTagInError) {
nsresult result=NS_OK; nsresult result=NS_OK;
// adjust line number to what it will be after we finish writing this tag // adjust line number to what it will be after we finish writing this tag
@ -997,9 +997,8 @@ nsresult CViewSourceHTML::WriteTag(PRInt32 aTagType,const nsAString & aText,PRIn
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
if (kBeforeText[aTagType][0] != 0) { if (kBeforeText[aTagType][0] != 0) {
nsAutoString beforeText; theContext.mITextToken.SetIndirectString(
beforeText.AssignWithConversion(kBeforeText[aTagType]); NS_ConvertASCIItoUTF16(kBeforeText[aTagType]));
theContext.mITextToken.SetIndirectString(beforeText);
nsCParserNode theNode(&theContext.mITextToken, 0/*stack token*/); nsCParserNode theNode(&theContext.mITextToken, 0/*stack token*/);
mSink->AddLeaf(theNode); mSink->AddLeaf(theNode);
} }
@ -1052,15 +1051,16 @@ nsresult CViewSourceHTML::WriteTag(PRInt32 aTagType,const nsAString & aText,PRIn
result=WriteAttributes(attrCount); result=WriteAttributes(attrCount);
} }
if (kAfterText[aTagType][0] != 0) { // Tokens are set in error if their ending > is not there, so don't output
nsAutoString afterText; // the after-text
afterText.AssignWithConversion(kAfterText[aTagType]); if (!aTagInError && kAfterText[aTagType][0] != 0) {
theContext.mITextToken.SetIndirectString(afterText); theContext.mITextToken.SetIndirectString(
NS_ConvertASCIItoUTF16(kAfterText[aTagType]));
nsCParserNode theNode(&theContext.mITextToken, 0/*stack token*/); nsCParserNode theNode(&theContext.mITextToken, 0/*stack token*/);
mSink->AddLeaf(theNode); mSink->AddLeaf(theNode);
} }
#ifdef DUMP_TO_FILE #ifdef DUMP_TO_FILE
if (gDumpFile && kDumpFileAfterText[aTagType][0]) if (!aTagInError && gDumpFile && kDumpFileAfterText[aTagType][0])
fprintf(gDumpFile, kDumpFileAfterText[aTagType]); fprintf(gDumpFile, kDumpFileAfterText[aTagType]);
#endif // DUMP_TO_FILE #endif // DUMP_TO_FILE
@ -1097,7 +1097,7 @@ NS_IMETHODIMP CViewSourceHTML::HandleToken(CToken* aToken,nsIParser* aParser) {
++mTagCount; ++mTagCount;
const nsAString& startValue = aToken->GetStringValue(); const nsAString& startValue = aToken->GetStringValue();
result=WriteTag(mStartTag,startValue,aToken->GetAttributeCount(),PR_TRUE); result=WriteTag(mStartTag,startValue,aToken->GetAttributeCount(),aToken->IsInError());
if((ePlainText!=mDocType) && mParser && (NS_OK==result)) { if((ePlainText!=mDocType) && mParser && (NS_OK==result)) {
result = mSink->NotifyTagObservers(&theContext.mTokenNode); result = mSink->NotifyTagObservers(&theContext.mTokenNode);
@ -1112,7 +1112,7 @@ NS_IMETHODIMP CViewSourceHTML::HandleToken(CToken* aToken,nsIParser* aParser) {
} }
const nsAString& endValue = aToken->GetStringValue(); const nsAString& endValue = aToken->GetStringValue();
result=WriteTag(mEndTag,endValue,aToken->GetAttributeCount(),PR_TRUE); result=WriteTag(mEndTag,endValue,aToken->GetAttributeCount(),aToken->IsInError());
} }
break; break;
@ -1121,10 +1121,10 @@ NS_IMETHODIMP CViewSourceHTML::HandleToken(CToken* aToken,nsIParser* aParser) {
nsAutoString theStr; nsAutoString theStr;
theStr.AssignLiteral("<!"); theStr.AssignLiteral("<!");
theStr.Append(aToken->GetStringValue()); theStr.Append(aToken->GetStringValue());
// Treat CDATA sections specially because they remember their last if (!aToken->IsInError()) {
// character and can come back malformed. theStr.AppendLiteral(">");
// theStr.AppendLiteral(">"); }
result=WriteTag(mCDATATag,theStr,0,PR_TRUE); result=WriteTag(mCDATATag,theStr,0,aToken->IsInError());
} }
break; break;
@ -1133,8 +1133,10 @@ NS_IMETHODIMP CViewSourceHTML::HandleToken(CToken* aToken,nsIParser* aParser) {
nsAutoString theStr; nsAutoString theStr;
theStr.AssignLiteral("<!"); theStr.AssignLiteral("<!");
theStr.Append(aToken->GetStringValue()); theStr.Append(aToken->GetStringValue());
theStr.AppendLiteral(">"); if (!aToken->IsInError()) {
result=WriteTag(mMarkupDeclaration,theStr,0,PR_TRUE); theStr.AppendLiteral(">");
}
result=WriteTag(mMarkupDeclaration,theStr,0,aToken->IsInError());
} }
break; break;
@ -1142,14 +1144,14 @@ NS_IMETHODIMP CViewSourceHTML::HandleToken(CToken* aToken,nsIParser* aParser) {
{ {
nsAutoString theStr; nsAutoString theStr;
aToken->AppendSourceTo(theStr); aToken->AppendSourceTo(theStr);
result=WriteTag(mCommentTag,theStr,0,PR_TRUE); result=WriteTag(mCommentTag,theStr,0,aToken->IsInError());
} }
break; break;
case eToken_doctypeDecl: case eToken_doctypeDecl:
{ {
const nsAString& doctypeValue = aToken->GetStringValue(); const nsAString& doctypeValue = aToken->GetStringValue();
result=WriteTag(mDocTypeTag,doctypeValue,0,PR_TRUE); result=WriteTag(mDocTypeTag,doctypeValue,0,aToken->IsInError());
} }
break; break;
@ -1182,7 +1184,7 @@ NS_IMETHODIMP CViewSourceHTML::HandleToken(CToken* aToken,nsIParser* aParser) {
case eToken_text: case eToken_text:
{ {
const nsAString& str = aToken->GetStringValue(); const nsAString& str = aToken->GetStringValue();
result=WriteTag(mText,str,aToken->GetAttributeCount(),PR_TRUE); result=WriteTag(mText,str,aToken->GetAttributeCount(),aToken->IsInError());
++mTokenCount; ++mTokenCount;
if (NS_VIEWSOURCE_TOKENS_PER_BLOCK > 0 && if (NS_VIEWSOURCE_TOKENS_PER_BLOCK > 0 &&
mTokenCount > NS_VIEWSOURCE_TOKENS_PER_BLOCK && !str.IsEmpty()) { mTokenCount > NS_VIEWSOURCE_TOKENS_PER_BLOCK && !str.IsEmpty()) {
@ -1204,12 +1206,12 @@ NS_IMETHODIMP CViewSourceHTML::HandleToken(CToken* aToken,nsIParser* aParser) {
theStr.Assign(NS_LITERAL_STRING("#") + theStr); theStr.Assign(NS_LITERAL_STRING("#") + theStr);
} }
} }
result=WriteTag(mEntityTag,theStr,0,PR_FALSE); result=WriteTag(mEntityTag,theStr,0,aToken->IsInError());
} }
break; break;
case eToken_instruction: case eToken_instruction:
result=WriteTag(mPITag,aToken->GetStringValue(),0,PR_TRUE); result=WriteTag(mPITag,aToken->GetStringValue(),0,aToken->IsInError());
default: default:
result=NS_OK; result=NS_OK;

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

@ -85,7 +85,7 @@ private:
nsresult WriteTag(PRInt32 tagType, nsresult WriteTag(PRInt32 tagType,
const nsAString &aText, const nsAString &aText,
PRInt32 attrCount, PRInt32 attrCount,
PRBool aNewlineRequired); PRBool aTagInError);
nsresult WriteAttributes(PRInt32 attrCount); nsresult WriteAttributes(PRInt32 attrCount);
nsresult GenerateSummary(); nsresult GenerateSummary();