Bug 748365 - xpath: Don't progress past end in nextToken, remove pushBack() logic. r=sicking

This commit is contained in:
John Schoenick 2012-04-26 14:46:44 -07:00
Родитель a0dd043f0c
Коммит 74f0bb2104
4 изменённых файлов: 53 добавлений и 44 удалений

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

@ -75,23 +75,25 @@ txExprLexer::~txExprLexer()
Token*
txExprLexer::nextToken()
{
NS_ASSERTION(mCurrentItem, "nextToken called beyoned the end");
if (!mCurrentItem) {
NS_NOTREACHED("nextToken called on uninitialized lexer");
return nsnull;
}
if (mCurrentItem->mType == Token::END) {
// Do not progress beyond the end token
return mCurrentItem;
}
Token* token = mCurrentItem;
mCurrentItem = mCurrentItem->mNext;
return token;
}
void
txExprLexer::pushBack()
{
mCurrentItem = mCurrentItem ? mCurrentItem->mPrevious : mLastItem;
}
void
txExprLexer::addToken(Token* aToken)
{
if (mLastItem) {
aToken->mPrevious = mLastItem;
mLastItem->mNext = aToken;
}
if (!mFirstItem) {

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

@ -128,16 +128,14 @@ public:
: mStart(aStart),
mEnd(aEnd),
mType(aType),
mNext(nsnull),
mPrevious(nsnull)
mNext(nsnull)
{
}
Token(iterator aChar, Type aType)
: mStart(aChar),
mEnd(aChar + 1),
mType(aType),
mNext(nsnull),
mPrevious(nsnull)
mNext(nsnull)
{
}
@ -149,8 +147,6 @@ public:
iterator mStart, mEnd;
Type mType;
Token* mNext;
// XXX mPrevious needed for pushBack(), do we pushBack more than once?
Token* mPrevious;
};
/**
@ -186,12 +182,19 @@ public:
Token* nextToken();
Token* peek()
{
NS_ASSERTION(mCurrentItem, "peek called uninitialized lexer");
return mCurrentItem;
}
void pushBack();
Token* peekAhead()
{
NS_ASSERTION(mCurrentItem, "peekAhead called on uninitialized lexer");
// Don't peek past the end node
return (mCurrentItem && mCurrentItem->mNext) ? mCurrentItem->mNext : mCurrentItem;
}
bool hasMoreTokens()
{
return (mCurrentItem->mType != Token::END);
NS_ASSERTION(mCurrentItem, "HasMoreTokens called on uninitialized lexer");
return (mCurrentItem && mCurrentItem->mType != Token::END);
}
/**

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

@ -337,9 +337,9 @@ txExprParser::createExpr(txExprLexer& lexer, txIParseContext* aContext,
}
}
Token* tok = lexer.nextToken();
short tokPrecedence = precedence(tok);
short tokPrecedence = precedence(lexer.peek());
if (tokPrecedence != 0) {
Token* tok = lexer.nextToken();
while (!exprs.isEmpty() && tokPrecedence
<= precedence(static_cast<Token*>(ops.peek()))) {
// can't use expr as argument due to order of evaluation
@ -357,7 +357,6 @@ txExprParser::createExpr(txExprLexer& lexer, txIParseContext* aContext,
ops.push(tok);
}
else {
lexer.pushBack();
done = true;
}
}
@ -385,16 +384,16 @@ txExprParser::createFilterOrStep(txExprLexer& lexer, txIParseContext* aContext,
*aResult = nsnull;
nsresult rv = NS_OK;
Token* tok = lexer.nextToken();
Token* tok = lexer.peek();
nsAutoPtr<Expr> expr;
switch (tok->mType) {
case Token::FUNCTION_NAME_AND_PAREN:
lexer.pushBack();
rv = createFunctionCall(lexer, aContext, getter_Transfers(expr));
NS_ENSURE_SUCCESS(rv, rv);
break;
case Token::VAR_REFERENCE :
lexer.nextToken();
{
nsCOMPtr<nsIAtom> prefix, lName;
PRInt32 nspace;
@ -406,24 +405,26 @@ txExprParser::createFilterOrStep(txExprLexer& lexer, txIParseContext* aContext,
}
break;
case Token::L_PAREN:
lexer.nextToken();
rv = createExpr(lexer, aContext, getter_Transfers(expr));
NS_ENSURE_SUCCESS(rv, rv);
if (lexer.nextToken()->mType != Token::R_PAREN) {
lexer.pushBack();
if (lexer.peek()->mType != Token::R_PAREN) {
return NS_ERROR_XPATH_PAREN_EXPECTED;
}
lexer.nextToken();
break;
case Token::LITERAL :
lexer.nextToken();
expr = new txLiteralExpr(tok->Value());
break;
case Token::NUMBER:
{
lexer.nextToken();
expr = new txLiteralExpr(txDouble::toDouble(tok->Value()));
break;
}
default:
lexer.pushBack();
return createLocationStep(lexer, aContext, aResult);
}
@ -582,9 +583,10 @@ txExprParser::createLocationStep(txExprLexer& lexer, txIParseContext* aContext,
//-- get NodeTest unless an AbbreviatedStep was found
nsresult rv = NS_OK;
if (!nodeTest) {
tok = lexer.nextToken();
tok = lexer.peek();
if (tok->mType == Token::CNAME) {
lexer.nextToken();
// resolve QName
nsCOMPtr<nsIAtom> prefix, lName;
PRInt32 nspace;
@ -600,7 +602,6 @@ txExprParser::createLocationStep(txExprLexer& lexer, txIParseContext* aContext,
static_cast<PRUint16>(txXPathNodeType::ELEMENT_NODE));
}
else {
lexer.pushBack();
rv = createNodeTypeTest(lexer, getter_Transfers(nodeTest));
NS_ENSURE_SUCCESS(rv, rv);
}
@ -628,25 +629,29 @@ txExprParser::createNodeTypeTest(txExprLexer& lexer, txNodeTest** aTest)
*aTest = 0;
nsAutoPtr<txNodeTypeTest> nodeTest;
Token* nodeTok = lexer.nextToken();
Token* nodeTok = lexer.peek();
switch (nodeTok->mType) {
case Token::COMMENT_AND_PAREN:
lexer.nextToken();
nodeTest = new txNodeTypeTest(txNodeTypeTest::COMMENT_TYPE);
break;
case Token::NODE_AND_PAREN:
lexer.nextToken();
nodeTest = new txNodeTypeTest(txNodeTypeTest::NODE_TYPE);
break;
case Token::PROC_INST_AND_PAREN:
lexer.nextToken();
nodeTest = new txNodeTypeTest(txNodeTypeTest::PI_TYPE);
break;
case Token::TEXT_AND_PAREN:
lexer.nextToken();
nodeTest = new txNodeTypeTest(txNodeTypeTest::TEXT_TYPE);
break;
default:
lexer.pushBack();
return NS_ERROR_XPATH_NO_NODE_TYPE_TEST;
}
NS_ENSURE_TRUE(nodeTest, NS_ERROR_OUT_OF_MEMORY);
if (nodeTok->mType == Token::PROC_INST_AND_PAREN &&
@ -654,10 +659,10 @@ txExprParser::createNodeTypeTest(txExprLexer& lexer, txNodeTest** aTest)
Token* tok = lexer.nextToken();
nodeTest->setNodeName(tok->Value());
}
if (lexer.nextToken()->mType != Token::R_PAREN) {
lexer.pushBack();
if (lexer.peek()->mType != Token::R_PAREN) {
return NS_ERROR_XPATH_PAREN_EXPECTED;
}
lexer.nextToken();
*aTest = nodeTest.forget();
return NS_OK;
@ -679,12 +684,11 @@ txExprParser::createPathExpr(txExprLexer& lexer, txIParseContext* aContext,
// is this a root expression?
if (tok->mType == Token::PARENT_OP) {
lexer.nextToken();
if (!isLocationStepToken(lexer.peek())) {
if (!isLocationStepToken(lexer.peekAhead())) {
lexer.nextToken();
*aResult = new RootExpr();
return NS_OK;
}
lexer.pushBack();
}
// parse first step (possibly a FilterExpr)
@ -721,8 +725,7 @@ txExprParser::createPathExpr(txExprLexer& lexer, txIParseContext* aContext,
// this is ugly
while (1) {
PathExpr::PathOperator pathOp;
tok = lexer.nextToken();
switch (tok->mType) {
switch (lexer.peek()->mType) {
case Token::ANCESTOR_OP :
pathOp = PathExpr::DESCENDANT_OP;
break;
@ -730,11 +733,11 @@ txExprParser::createPathExpr(txExprLexer& lexer, txIParseContext* aContext,
pathOp = PathExpr::RELATIVE_OP;
break;
default:
lexer.pushBack();
*aResult = pathExpr.forget();
return NS_OK;
}
lexer.nextToken();
rv = createLocationStep(lexer, aContext, getter_Transfers(expr));
NS_ENSURE_SUCCESS(rv, rv);
@ -828,10 +831,10 @@ txExprParser::parsePredicates(PredicateList* aPredicateList,
expr.forget();
if (lexer.nextToken()->mType != Token::R_BRACKET) {
lexer.pushBack();
if (lexer.peek()->mType != Token::R_BRACKET) {
return NS_ERROR_XPATH_BRACKET_EXPECTED;
}
lexer.nextToken();
}
return NS_OK;
}
@ -865,13 +868,14 @@ txExprParser::parseParameters(FunctionCall* aFnCall, txExprLexer& lexer,
NS_ENSURE_SUCCESS(rv, rv);
}
switch (lexer.nextToken()->mType) {
switch (lexer.peek()->mType) {
case Token::R_PAREN :
lexer.nextToken();
return NS_OK;
case Token::COMMA: //-- param separator
lexer.nextToken();
break;
default:
lexer.pushBack();
return NS_ERROR_XPATH_PAREN_EXPECTED;
}
}

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

@ -316,10 +316,11 @@ nsresult txPatternParser::createStepPattern(txExprLexer& aLexer,
aLexer.nextToken();
isAttr = true;
}
tok = aLexer.nextToken();
txNodeTest* nodeTest;
if (tok->mType == Token::CNAME) {
if (aLexer.peek()->mType == Token::CNAME) {
tok = aLexer.nextToken();
// resolve QName
nsCOMPtr<nsIAtom> prefix, lName;
PRInt32 nspace;
@ -339,7 +340,6 @@ nsresult txPatternParser::createStepPattern(txExprLexer& aLexer,
}
}
else {
aLexer.pushBack();
rv = createNodeTypeTest(aLexer, &nodeTest);
NS_ENSURE_SUCCESS(rv, rv);
}