From 7ea8efe0cb3199566b86a2b7ad4cb99df8620324 Mon Sep 17 00:00:00 2001 From: wolfbeast Date: Sat, 6 Apr 2019 11:11:04 +0200 Subject: Report errors for bad increment/decrement operands using explicitly-specified offsets. --- js/src/frontend/Parser.cpp | 55 ++++++++++++++++++++++------------------------ js/src/frontend/Parser.h | 2 +- 2 files changed, 27 insertions(+), 30 deletions(-) (limited to 'js/src') diff --git a/js/src/frontend/Parser.cpp b/js/src/frontend/Parser.cpp index 3e7c25c19..3b1cadbff 100644 --- a/js/src/frontend/Parser.cpp +++ b/js/src/frontend/Parser.cpp @@ -7776,31 +7776,28 @@ Parser::isValidSimpleAssignmentTarget(Node node, template bool -Parser::checkAndMarkAsIncOperand(Node target) +Parser::checkIncDecOperand(Node operand, uint32_t operandOffset) { - if (handler.isNameAnyParentheses(target)) { - if (const char* chars = handler.nameIsArgumentsEvalAnyParentheses(target, context)) { - if (!reportWithNode(ParseStrictError, pc->sc()->strict(), target, - JSMSG_BAD_STRICT_ASSIGN, chars)) - { + if (handler.isNameAnyParentheses(operand)) { + if (const char* chars = handler.nameIsArgumentsEvalAnyParentheses(operand, context)) { + if (!strictModeErrorAt(operandOffset, JSMSG_BAD_STRICT_ASSIGN, chars)) return false; - } } - } else if (handler.isPropertyAccess(target)) { + } else if (handler.isPropertyAccess(operand)) { // 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 // 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 // otherwise warn. - if (!reportWithNode(ParseStrictError, pc->sc()->strict(), target, JSMSG_BAD_INCOP_OPERAND)) + if (!strictModeErrorAt(operandOffset, JSMSG_BAD_INCOP_OPERAND)) return false; } else { - reportWithNode(ParseError, pc->sc()->strict(), target, JSMSG_BAD_INCOP_OPERAND); + errorAt(operandOffset, JSMSG_BAD_INCOP_OPERAND); return false; } - MOZ_ASSERT(isValidSimpleAssignmentTarget(target, PermitAssignmentToFunctionCalls), + MOZ_ASSERT(isValidSimpleAssignmentTarget(operand, PermitAssignmentToFunctionCalls), "inconsistent increment/decrement operand validation"); return true; } @@ -7865,14 +7862,14 @@ Parser::unaryExpr(YieldHandling yieldHandling, TripledotHandling t TokenKind tt2; if (!tokenStream.getToken(&tt2, TokenStream::Operand)) return null(); - Node pn2 = memberExpr(yieldHandling, TripledotProhibited, tt2); - if (!pn2) - return null(); - if (!checkAndMarkAsIncOperand(pn2)) + + uint32_t operandOffset = pos().begin; + Node operand = memberExpr(yieldHandling, TripledotProhibited, tt2); + if (!operand || !checkIncDecOperand(operand, operandOffset)) return null(); + return handler.newUpdate((tt == TOK_INC) ? PNK_PREINCREMENT : PNK_PREDECREMENT, - begin, - pn2); + begin, operand); } case TOK_DELETE: { @@ -7912,23 +7909,23 @@ Parser::unaryExpr(YieldHandling yieldHandling, TripledotHandling t } default: { - Node pn = memberExpr(yieldHandling, tripledotHandling, tt, /* allowCallSyntax = */ true, + Node expr = memberExpr(yieldHandling, tripledotHandling, tt, /* allowCallSyntax = */ true, possibleError, invoked); - if (!pn) + if (!expr) return null(); /* Don't look across a newline boundary for a postfix incop. */ if (!tokenStream.peekTokenSameLine(&tt)) return null(); - if (tt == TOK_INC || tt == TOK_DEC) { - tokenStream.consumeKnownToken(tt); - if (!checkAndMarkAsIncOperand(pn)) - return null(); - return handler.newUpdate((tt == TOK_INC) ? PNK_POSTINCREMENT : PNK_POSTDECREMENT, - begin, - pn); - } - return pn; + + if (tt != TOK_INC && tt != TOK_DEC) + return expr; + + tokenStream.consumeKnownToken(tt); + if (!checkIncDecOperand(expr, begin)) + return null(); + return handler.newUpdate((tt == TOK_INC) ? PNK_POSTINCREMENT : PNK_POSTDECREMENT, + begin, expr); } } } diff --git a/js/src/frontend/Parser.h b/js/src/frontend/Parser.h index 0baaac3bc..a7e48c1a4 100644 --- a/js/src/frontend/Parser.h +++ b/js/src/frontend/Parser.h @@ -1368,7 +1368,7 @@ class Parser final : private JS::AutoGCRooter, public StrictModeGetter FunctionCallBehavior behavior = ForbidAssignmentToFunctionCalls); private: - bool checkAndMarkAsIncOperand(Node kid); + bool checkIncDecOperand(Node operand, uint32_t operandOffset); bool checkStrictAssignment(Node lhs); bool checkStrictBinding(PropertyName* name, TokenPos pos); -- cgit v1.2.3