Strict mode eval/arguments LHS.

Review URL: http://codereview.chromium.org/6335013/

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@6503 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
mmaly@chromium.org 2011-01-26 19:21:46 +00:00
parent 498e3ce3cc
commit d07f1d62ff
4 changed files with 105 additions and 0 deletions

View File

@ -241,6 +241,9 @@ function FormatMessage(message) {
strict_duplicate_property: "Duplicate data property in object literal not allowed in strict mode",
accessor_data_property: "Object literal may not have data and accessor property with the same name",
accessor_get_set: "Object literal may not have multiple get/set accessors with the same name",
strict_lhs_eval_assignment: "Assignment to eval or arguments is not allowed in strict mode",
strict_lhs_postfix: "Postfix increment/decrement may not have eval or arguments operand in strict mode",
strict_lhs_prefix: "Prefix increment/decrement may not have eval or arguments operand in strict mode",
};
}
var format = kMessages[message.type];

View File

@ -2292,6 +2292,11 @@ Expression* Parser::ParseAssignmentExpression(bool accept_IN, bool* ok) {
expression = NewThrowReferenceError(type);
}
if (temp_scope_->StrictMode()) {
// Assignment to eval or arguments is disallowed in strict mode.
CheckStrictModeLValue(expression, "strict_lhs_assignment", CHECK_OK);
}
Token::Value op = Next(); // Get assignment operator.
int pos = scanner().location().beg_pos;
Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK);
@ -2518,6 +2523,12 @@ Expression* Parser::ParseUnaryExpression(bool* ok) {
Handle<String> type = Factory::invalid_lhs_in_prefix_op_symbol();
expression = NewThrowReferenceError(type);
}
if (temp_scope_->StrictMode()) {
// Prefix expression operand in strict mode may not be eval or arguments.
CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK);
}
int position = scanner().location().beg_pos;
IncrementOperation* increment = new IncrementOperation(op, expression);
return new CountOperation(true /* prefix */, increment, position);
@ -2543,6 +2554,12 @@ Expression* Parser::ParsePostfixExpression(bool* ok) {
Handle<String> type = Factory::invalid_lhs_in_postfix_op_symbol();
expression = NewThrowReferenceError(type);
}
if (temp_scope_->StrictMode()) {
// Postfix expression operand in strict mode may not be eval or arguments.
CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK);
}
Token::Value next = Next();
int position = scanner().location().beg_pos;
IncrementOperation* increment = new IncrementOperation(next, expression);
@ -3692,6 +3709,24 @@ Handle<String> Parser::ParseIdentifierName(bool* ok) {
return GetSymbol(ok);
}
// Checks LHS expression for assignment and prefix/postfix increment/decrement
// in strict mode.
void Parser::CheckStrictModeLValue(Expression* expression,
const char* error,
bool* ok) {
ASSERT(temp_scope_->StrictMode());
VariableProxy* lhs = expression != NULL
? expression->AsVariableProxy()
: NULL;
if (lhs != NULL && !lhs->is_this() && IsEvalOrArguments(lhs->name())) {
ReportMessage(error, Vector<const char*>::empty());
*ok = false;
}
}
// Checks whether octal literal last seen is between beg_pos and end_pos.
// If so, reports an error.
void Parser::CheckOctalLiteral(int beg_pos, int end_pos, bool* ok) {

View File

@ -613,6 +613,11 @@ class Parser {
bool* is_set,
bool* ok);
// Strict mode validation of LValue expressions
void CheckStrictModeLValue(Expression* expression,
const char* error,
bool* ok);
// Strict mode octal literal validation.
void CheckOctalLiteral(int beg_pos, int end_pos, bool* ok);

View File

@ -203,3 +203,65 @@ assertThrows("var x = { 'foo': 'data', get foo() { } };", SyntaxError)
assertThrows("var x = { get 'foo'() { }, 'foo': 'data' };", SyntaxError)
assertThrows("var x = { '12': 1, get '12'(){}};", SyntaxError);
assertThrows("var x = { '12': 1, get 12(){}};", SyntaxError);
// Assignment to eval or arguments
CheckStrictMode("function strict() { eval = undefined; }", SyntaxError)
CheckStrictMode("function strict() { arguments = undefined; }", SyntaxError)
CheckStrictMode("function strict() { print(eval = undefined); }", SyntaxError)
CheckStrictMode("function strict() { print(arguments = undefined); }", SyntaxError)
CheckStrictMode("function strict() { var x = eval = undefined; }", SyntaxError)
CheckStrictMode("function strict() { var x = arguments = undefined; }", SyntaxError)
// Compound assignment to eval or arguments
CheckStrictMode("function strict() { eval *= undefined; }", SyntaxError)
CheckStrictMode("function strict() { arguments /= undefined; }", SyntaxError)
CheckStrictMode("function strict() { print(eval %= undefined); }", SyntaxError)
CheckStrictMode("function strict() { print(arguments %= undefined); }", SyntaxError)
CheckStrictMode("function strict() { var x = eval += undefined; }", SyntaxError)
CheckStrictMode("function strict() { var x = arguments -= undefined; }", SyntaxError)
CheckStrictMode("function strict() { eval <<= undefined; }", SyntaxError)
CheckStrictMode("function strict() { arguments >>= undefined; }", SyntaxError)
CheckStrictMode("function strict() { print(eval >>>= undefined); }", SyntaxError)
CheckStrictMode("function strict() { print(arguments &= undefined); }", SyntaxError)
CheckStrictMode("function strict() { var x = eval ^= undefined; }", SyntaxError)
CheckStrictMode("function strict() { var x = arguments |= undefined; }", SyntaxError)
// Postfix increment with eval or arguments
CheckStrictMode("function strict() { eval++; }", SyntaxError)
CheckStrictMode("function strict() { arguments++; }", SyntaxError)
CheckStrictMode("function strict() { print(eval++); }", SyntaxError)
CheckStrictMode("function strict() { print(arguments++); }", SyntaxError)
CheckStrictMode("function strict() { var x = eval++; }", SyntaxError)
CheckStrictMode("function strict() { var x = arguments++; }", SyntaxError)
// Postfix decrement with eval or arguments
CheckStrictMode("function strict() { eval--; }", SyntaxError)
CheckStrictMode("function strict() { arguments--; }", SyntaxError)
CheckStrictMode("function strict() { print(eval--); }", SyntaxError)
CheckStrictMode("function strict() { print(arguments--); }", SyntaxError)
CheckStrictMode("function strict() { var x = eval--; }", SyntaxError)
CheckStrictMode("function strict() { var x = arguments--; }", SyntaxError)
// Prefix increment with eval or arguments
CheckStrictMode("function strict() { ++eval; }", SyntaxError)
CheckStrictMode("function strict() { ++arguments; }", SyntaxError)
CheckStrictMode("function strict() { print(++eval); }", SyntaxError)
CheckStrictMode("function strict() { print(++arguments); }", SyntaxError)
CheckStrictMode("function strict() { var x = ++eval; }", SyntaxError)
CheckStrictMode("function strict() { var x = ++arguments; }", SyntaxError)
// Prefix decrement with eval or arguments
CheckStrictMode("function strict() { --eval; }", SyntaxError)
CheckStrictMode("function strict() { --arguments; }", SyntaxError)
CheckStrictMode("function strict() { print(--eval); }", SyntaxError)
CheckStrictMode("function strict() { print(--arguments); }", SyntaxError)
CheckStrictMode("function strict() { var x = --eval; }", SyntaxError)
CheckStrictMode("function strict() { var x = --arguments; }", SyntaxError)
// Prefix unary operators other than delete, ++, -- are valid in strict mode
function StrictModeUnaryOperators() {
"use strict";
var x = [void eval, typeof eval, +eval, -eval, ~eval, !eval];
var y = [void arguments, typeof arguments,
+arguments, -arguments, ~arguments, !arguments];
}