Report errors for bad increment/decrement operands using

explicitly-specified offsets.
This commit is contained in:
wolfbeast 2019-04-06 11:11:04 +02:00 • committed by Roy Tam
commit a389b4e151
2 changed files with 27 additions and 30 deletions

View file

@ -7776,31 +7776,28 @@ Parser<ParseHandler>::isValidSimpleAssignmentTarget(Node node,
template <typename ParseHandler> template <typename ParseHandler>
bool bool
Parser<ParseHandler>::checkAndMarkAsIncOperand(Node target) Parser<ParseHandler>::checkIncDecOperand(Node operand, uint32_t operandOffset)
{ {
if (handler.isNameAnyParentheses(target)) { if (handler.isNameAnyParentheses(operand)) {
if (const char* chars = handler.nameIsArgumentsEvalAnyParentheses(target, context)) { if (const char* chars = handler.nameIsArgumentsEvalAnyParentheses(operand, context)) {
if (!reportWithNode(ParseStrictError, pc->sc()->strict(), target, if (!strictModeErrorAt(operandOffset, JSMSG_BAD_STRICT_ASSIGN, chars))
JSMSG_BAD_STRICT_ASSIGN, chars))
{
return false; return false;
}
} }
} else if (handler.isPropertyAccess(target)) { } else if (handler.isPropertyAccess(operand)) {
// Permitted: no additional testing/fixup needed. // Permitted: no additional testing/fixup needed.
} else if (handler.isFunctionCall(target)) { } else if (handler.isFunctionCall(operand)) {
// Assignment to function calls is forbidden in ES6. We're still // Assignment to function calls is forbidden in ES6. We're still
// somewhat concerned about sites using this in dead code, so forbid it // somewhat concerned about sites using this in dead code, so forbid it
// only in strict mode code (or if the werror option has been set), and // only in strict mode code (or if the werror option has been set), and
// otherwise warn. // otherwise warn.
if (!reportWithNode(ParseStrictError, pc->sc()->strict(), target, JSMSG_BAD_INCOP_OPERAND)) if (!strictModeErrorAt(operandOffset, JSMSG_BAD_INCOP_OPERAND))
return false; return false;
} else { } else {
reportWithNode(ParseError, pc->sc()->strict(), target, JSMSG_BAD_INCOP_OPERAND); errorAt(operandOffset, JSMSG_BAD_INCOP_OPERAND);
return false; return false;
} }
MOZ_ASSERT(isValidSimpleAssignmentTarget(target, PermitAssignmentToFunctionCalls), MOZ_ASSERT(isValidSimpleAssignmentTarget(operand, PermitAssignmentToFunctionCalls),
"inconsistent increment/decrement operand validation"); "inconsistent increment/decrement operand validation");
return true; return true;
} }
@ -7865,14 +7862,14 @@ Parser<ParseHandler>::unaryExpr(YieldHandling yieldHandling, TripledotHandling t
TokenKind tt2; TokenKind tt2;
if (!tokenStream.getToken(&tt2, TokenStream::Operand)) if (!tokenStream.getToken(&tt2, TokenStream::Operand))
return null(); return null();
Node pn2 = memberExpr(yieldHandling, TripledotProhibited, tt2);
if (!pn2) uint32_t operandOffset = pos().begin;
return null(); Node operand = memberExpr(yieldHandling, TripledotProhibited, tt2);
if (!checkAndMarkAsIncOperand(pn2)) if (!operand || !checkIncDecOperand(operand, operandOffset))
return null(); return null();
return handler.newUpdate((tt == TOK_INC) ? PNK_PREINCREMENT : PNK_PREDECREMENT, return handler.newUpdate((tt == TOK_INC) ? PNK_PREINCREMENT : PNK_PREDECREMENT,
begin, begin, operand);
pn2);
} }
case TOK_DELETE: { case TOK_DELETE: {
@ -7912,23 +7909,23 @@ Parser<ParseHandler>::unaryExpr(YieldHandling yieldHandling, TripledotHandling t
} }
default: { default: {
Node pn = memberExpr(yieldHandling, tripledotHandling, tt, /* allowCallSyntax = */ true, Node expr = memberExpr(yieldHandling, tripledotHandling, tt, /* allowCallSyntax = */ true,
possibleError, invoked); possibleError, invoked);
if (!pn) if (!expr)
return null(); return null();
/* Don't look across a newline boundary for a postfix incop. */ /* Don't look across a newline boundary for a postfix incop. */
if (!tokenStream.peekTokenSameLine(&tt)) if (!tokenStream.peekTokenSameLine(&tt))
return null(); return null();
if (tt == TOK_INC || tt == TOK_DEC) {
tokenStream.consumeKnownToken(tt); if (tt != TOK_INC && tt != TOK_DEC)
if (!checkAndMarkAsIncOperand(pn)) return expr;
return null();
return handler.newUpdate((tt == TOK_INC) ? PNK_POSTINCREMENT : PNK_POSTDECREMENT, tokenStream.consumeKnownToken(tt);
begin, if (!checkIncDecOperand(expr, begin))
pn); return null();
} return handler.newUpdate((tt == TOK_INC) ? PNK_POSTINCREMENT : PNK_POSTDECREMENT,
return pn; begin, expr);
} }
} }
} }

View file

@ -1368,7 +1368,7 @@ class Parser final : private JS::AutoGCRooter, public StrictModeGetter
FunctionCallBehavior behavior = ForbidAssignmentToFunctionCalls); FunctionCallBehavior behavior = ForbidAssignmentToFunctionCalls);
private: private:
bool checkAndMarkAsIncOperand(Node kid); bool checkIncDecOperand(Node operand, uint32_t operandOffset);
bool checkStrictAssignment(Node lhs); bool checkStrictAssignment(Node lhs);
bool checkStrictBinding(PropertyName* name, TokenPos pos); bool checkStrictBinding(PropertyName* name, TokenPos pos);