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:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user