Revision: 6474
Author: [email protected]
Date: Tue Jan 25 09:21:45 2011
Log: Strict mode parameter validation.
http://code.google.com/p/v8/source/detail?r=6474
Modified:
/branches/bleeding_edge/src/parser.cc
/branches/bleeding_edge/src/scanner-base.h
/branches/bleeding_edge/src/scopes.h
/branches/bleeding_edge/test/mjsunit/strict-mode.js
=======================================
--- /branches/bleeding_edge/src/parser.cc Mon Jan 24 10:13:18 2011
+++ /branches/bleeding_edge/src/parser.cc Tue Jan 25 09:21:45 2011
@@ -3300,10 +3300,21 @@
// '(' (Identifier)*[','] ')'
Expect(Token::LPAREN, CHECK_OK);
int start_pos = scanner().location().beg_pos;
+ Scanner::Location name_loc = Scanner::NoLocation();
+ Scanner::Location dupe_loc = Scanner::NoLocation();
bool done = (peek() == Token::RPAREN);
while (!done) {
Handle<String> param_name = ParseIdentifier(CHECK_OK);
+
+ // Store locations for possible future error reports.
+ if (!name_loc.IsValid() && IsEvalOrArguments(param_name)) {
+ name_loc = scanner().location();
+ }
+ if (!dupe_loc.IsValid() && top_scope_->IsDeclared(param_name)) {
+ dupe_loc = scanner().location();
+ }
+
Variable* parameter = top_scope_->DeclareLocal(param_name,
Variable::VAR);
top_scope_->AddParameter(parameter);
num_parameters++;
@@ -3381,13 +3392,25 @@
if (temp_scope_->StrictMode()) {
if (IsEvalOrArguments(name)) {
int position = function_token_position != RelocInfo::kNoPosition
- ? function_token_position
- : (start_pos > 0 ? start_pos - 1 : start_pos);
+ ? function_token_position
+ : (start_pos > 0 ? start_pos - 1 : start_pos);
ReportMessageAt(Scanner::Location(position, start_pos),
"strict_function_name", Vector<const
char*>::empty());
*ok = false;
return NULL;
}
+ if (name_loc.IsValid()) {
+ ReportMessageAt(name_loc, "strict_param_name",
+ Vector<const char*>::empty());
+ *ok = false;
+ return NULL;
+ }
+ if (dupe_loc.IsValid()) {
+ ReportMessageAt(dupe_loc, "strict_param_dupe",
+ Vector<const char*>::empty());
+ *ok = false;
+ return NULL;
+ }
CheckOctalLiteral(start_pos, end_pos, CHECK_OK);
}
=======================================
--- /branches/bleeding_edge/src/scanner-base.h Mon Jan 24 10:13:18 2011
+++ /branches/bleeding_edge/src/scanner-base.h Tue Jan 25 09:21:45 2011
@@ -274,10 +274,19 @@
struct Location {
Location(int b, int e) : beg_pos(b), end_pos(e) { }
Location() : beg_pos(0), end_pos(0) { }
+
+ bool IsValid() const {
+ return beg_pos >= 0 && end_pos >= beg_pos;
+ }
+
int beg_pos;
int end_pos;
};
+ static Location NoLocation() {
+ return Location(-1, -1);
+ }
+
// Returns the location information for the current token
// (the token returned by Next()).
Location location() const { return current_.location; }
=======================================
--- /branches/bleeding_edge/src/scopes.h Tue Jan 18 15:01:50 2011
+++ /branches/bleeding_edge/src/scopes.h Tue Jan 25 09:21:45 2011
@@ -287,6 +287,17 @@
// The number of contexts between this and scope; zero if this == scope.
int ContextChainLength(Scope* scope);
+
+ //
---------------------------------------------------------------------------
+ // Strict mode support.
+ bool IsDeclared(Handle<String> name) {
+ // During formal parameter list parsing the scope only contains
+ // two variables inserted at initialization: "this" and "arguments".
+ // "this" is an invalid parameter name and "arguments" is invalid
parameter
+ // name in strict mode. Therefore looking up with the map which
includes
+ // "this" and "arguments" in addition to all formal parameters is safe.
+ return variables_.Lookup(name) != NULL;
+ }
//
---------------------------------------------------------------------------
// Debugging.
=======================================
--- /branches/bleeding_edge/test/mjsunit/strict-mode.js Mon Jan 24 10:13:18
2011
+++ /branches/bleeding_edge/test/mjsunit/strict-mode.js Tue Jan 25 09:21:45
2011
@@ -76,19 +76,19 @@
CheckStrictMode("function arguments() {}", SyntaxError)
// Function parameter named 'eval'.
-//CheckStrictMode("function foo(a, b, eval, c, d) {}", SyntaxError)
+CheckStrictMode("function foo(a, b, eval, c, d) {}", SyntaxError)
// Function parameter named 'arguments'.
-//CheckStrictMode("function foo(a, b, arguments, c, d) {}", SyntaxError)
+CheckStrictMode("function foo(a, b, arguments, c, d) {}", SyntaxError)
// Property accessor parameter named 'eval'.
-//CheckStrictMode("var o = { set foo(eval) {} }", SyntaxError)
+CheckStrictMode("var o = { set foo(eval) {} }", SyntaxError)
// Property accessor parameter named 'arguments'.
-//CheckStrictMode("var o = { set foo(arguments) {} }", SyntaxError)
+CheckStrictMode("var o = { set foo(arguments) {} }", SyntaxError)
// Duplicate function parameter name.
-//CheckStrictMode("function foo(a, b, c, d, b) {}", SyntaxError)
+CheckStrictMode("function foo(a, b, c, d, b) {}", SyntaxError)
// catch(eval)
CheckStrictMode("try{}catch(eval){};", SyntaxError)
@@ -103,10 +103,10 @@
CheckStrictMode("var arguments;", SyntaxError)
// Strict mode applies to the function in which the directive is used..
-//assertThrows('\
-//function foo(eval) {\
-// "use strict";\
-//}', SyntaxError);
+assertThrows('\
+function foo(eval) {\
+ "use strict";\
+}', SyntaxError);
// Strict mode doesn't affect the outer stop of strict code.
function NotStrict(eval) {
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev