Bug 83301 improve error reporting for Mismatched Tag XML, eg data:text/xml,<foo></bar>

r=heikki sr=shaver
thanks to tingley@sundell.net and bz


git-svn-id: svn://10.0.0.236/trunk@101088 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
timeless%mac.com
2001-08-15 06:48:59 +00:00
parent 7946a68c5d
commit 0b4ad7127e
2 changed files with 112 additions and 6 deletions

View File

@@ -364,10 +364,11 @@ nsExpatTokenizer::AddErrorMessageTokens(nsParserError* aError)
* in the content sink:
*
* <ParserError>
* XML Error: "contents of aError->description"
* Line Number: "contents of aError->lineNumber"
* XML Error: [aError->description]
* Location: [aError->sourceURL]
* Line Number: [aError->lineNumber], Column [aError->colNumber]
* <SourceText>
* "Contents of aError->sourceLine"
* [aError->sourceLine]
* "^ pointing at the error location"
* </SourceText>
* </ParserError>
@@ -387,6 +388,58 @@ nsExpatTokenizer::PushXMLErrorTokens(const char *aBuffer, PRUint32 aLength, PRBo
// Adjust the column number so that it is one based rather than zero based.
error->colNumber = XML_GetCurrentColumnNumber(mExpatParser) + 1;
error->description.AssignWithConversion(XML_ErrorString(error->code));
if (error->code==XML_ERROR_TAG_MISMATCH){
/*
* Certain things can be assumed about the token stream because of
* the way expat behaves. eg:
*
* - data:text/xml,</foo> is NOT WELL-FORMED
* - data:text/xml,<foo></bar> is a TAG_MISMATCH.
*
* We can assume that there is at least one extra open tag (the one we
* want), so balance is initially set to one.
*
* Then loop through the tokens:
* - Each time we see eToken_end (</tag>) increment balance, because
* that means there is another pair of tags we don't care about.
* - Each time we see eToken_start (<tag>) decrement balance because it
* matches a close tag (perhaps the MISMATCHed tag in which case
* balance should hit 0).
* - If balance ever hits zero, exit the loop. Because of the way
* balance is adjusted, if balance is zero expected *must* be a start
* tag.
*
* We must check expected in the condition in case expat or nsDeque go
* crazy and give us 0 (null) before balance reaches 0.
*/
nsDequeIterator current = mState->tokenDeque->End();
CToken *expected = NS_STATIC_CAST(CToken*,--current);
PRUint32 balance = 1;
while (expected) {
switch (expected->GetTokenType()) {
case eToken_start:
--balance;
break;
case eToken_end:
++balance;
break;
default:
break; // we don't care about newlines or other tokens
}
if (!balance) {
// if balance is zero, this must be a start tag
CStartToken *startToken=NS_STATIC_CAST(CStartToken*,expected);
error->description.Append(NS_LITERAL_STRING(". Expected: </"));
error->description.Append(startToken->GetStringValue());
error->description.Append(NS_LITERAL_STRING(">"));
break;
}
expected = NS_STATIC_CAST(CToken*,--current);
}
}
error->sourceURL.Assign((PRUnichar*)XML_GetBase(mExpatParser));
if (!aIsFinal) {
PRInt32 byteIndexRelativeToFile = 0;