Index: test/cctest/test-parsing.cc |
diff --git a/test/cctest/test-parsing.cc b/test/cctest/test-parsing.cc |
index 9d47ec1a225e1750d7405181301140ab5b99c5d5..5b19746f937b043524f77b260d7ad32de8ed295c 100644 |
--- a/test/cctest/test-parsing.cc |
+++ b/test/cctest/test-parsing.cc |
@@ -5638,3 +5638,153 @@ TEST(ArrowFunctionASIErrors) { |
RunParserSyncTest(context_data, data, kError, NULL, 0, always_flags, |
arraysize(always_flags)); |
} |
+ |
+ |
+TEST(StrongModeFreeVariablesDeclaredByPreviousScript) { |
+ i::FLAG_strong_mode = true; |
+ v8::V8::Initialize(); |
+ v8::HandleScope scope(CcTest::isolate()); |
+ v8::Context::Scope context_scope(v8::Context::New(CcTest::isolate())); |
+ v8::TryCatch try_catch; |
+ |
+ // Introduce a bunch of variables, in all language modes. |
+ const char* script1 = |
+ "var my_var1 = 0; \n" |
+ "function my_func1() { } \n" |
+ "const my_const1 = 0; \n"; |
+ CompileRun(v8_str(script1)); |
+ CHECK(!try_catch.HasCaught()); |
+ |
+ const char* script2 = |
+ "\"use strict\"; \n" |
+ "let my_var2 = 0; \n" |
+ "function my_func2() { } \n" |
+ "const my_const2 = 0 \n"; |
+ CompileRun(v8_str(script2)); |
+ CHECK(!try_catch.HasCaught()); |
+ |
+ const char* script3 = |
+ "\"use strong\"; \n" |
+ "let my_var3 = 0; \n" |
+ "function my_func3() { } \n" |
+ "const my_const3 = 0; \n"; |
+ CompileRun(v8_str(script3)); |
+ CHECK(!try_catch.HasCaught()); |
+ |
+ // Sloppy eval introduces variables in the surrounding scope. |
+ const char* script4 = |
+ "eval('var my_var4 = 0;') \n" |
+ "eval('function my_func4() { }') \n" |
+ "eval('const my_const4 = 0;') \n"; |
+ CompileRun(v8_str(script4)); |
+ CHECK(!try_catch.HasCaught()); |
+ |
+ // Test that referencing these variables work. |
+ const char* script5 = |
+ "\"use strong\"; \n" |
+ "my_var1; \n" |
+ "my_func1; \n" |
+ "my_const1; \n" |
+ "my_var2; \n" |
+ "my_func2; \n" |
+ "my_const2; \n" |
+ "my_var3; \n" |
+ "my_func3; \n" |
+ "my_const3; \n" |
+ "my_var4; \n" |
+ "my_func4; \n" |
+ "my_const4; \n"; |
+ CompileRun(v8_str(script5)); |
+ CHECK(!try_catch.HasCaught()); |
+} |
+ |
+ |
+TEST(StrongModeFreeVariablesDeclaredByLanguage) { |
+ i::FLAG_strong_mode = true; |
+ v8::V8::Initialize(); |
+ v8::HandleScope scope(CcTest::isolate()); |
+ v8::Context::Scope context_scope(v8::Context::New(CcTest::isolate())); |
+ v8::TryCatch try_catch; |
+ |
+ const char* script1 = |
+ "\"use strong\"; \n" |
+ "Math; \n" |
+ "RegExp; \n"; |
+ CompileRun(v8_str(script1)); |
+ CHECK(!try_catch.HasCaught()); |
+} |
+ |
+ |
+TEST(StrongModeFreeVariablesDeclaredInGlobalPrototype) { |
+ i::FLAG_strong_mode = true; |
+ v8::V8::Initialize(); |
+ v8::HandleScope scope(CcTest::isolate()); |
+ v8::Context::Scope context_scope(v8::Context::New(CcTest::isolate())); |
+ v8::TryCatch try_catch; |
+ |
+ const char* script1 = "this.__proto__.my_var = 0;\n"; |
+ CompileRun(v8_str(script1)); |
+ CHECK(!try_catch.HasCaught()); |
+ |
+ const char* script2 = |
+ "\"use strong\"; \n" |
+ "my_var; \n"; |
+ CompileRun(v8_str(script2)); |
+ CHECK(!try_catch.HasCaught()); |
+} |
+ |
+ |
+TEST(StrongModeFreeVariablesNotDeclared) { |
+ i::FLAG_strong_mode = true; |
+ v8::V8::Initialize(); |
+ v8::HandleScope scope(CcTest::isolate()); |
+ v8::Context::Scope context_scope(v8::Context::New(CcTest::isolate())); |
+ v8::TryCatch try_catch; |
+ |
+ // Test that referencing unintroduced variables in sloppy mode is ok. |
+ const char* script1 = |
+ "if (false) { \n" |
+ " not_there1; \n" |
+ "} \n"; |
+ CompileRun(v8_str(script1)); |
+ CHECK(!try_catch.HasCaught()); |
+ |
+ // But not in strong mode. |
+ { |
+ const char* script2 = |
+ "\"use strong\"; \n" |
+ "if (false) { \n" |
+ " not_there2; \n" |
+ "} \n"; |
+ v8::TryCatch try_catch2; |
+ v8::Script::Compile(v8_str(script2)); |
+ CHECK(try_catch2.HasCaught()); |
+ v8::String::Utf8Value exception(try_catch2.Exception()); |
+ CHECK_EQ(0, |
+ strcmp( |
+ "ReferenceError: In strong mode, using an undeclared global " |
+ "variable 'not_there2' is not allowed", |
+ *exception)); |
+ } |
+ |
+ // Check that the variable reference is detected inside a strong function too, |
+ // even if the script scope is not strong. |
+ { |
+ const char* script3 = |
+ "(function not_lazy() { \n" |
+ " \"use strong\"; \n" |
+ " if (false) { \n" |
+ " not_there3; \n" |
+ " } \n" |
+ "})(); \n"; |
+ v8::TryCatch try_catch2; |
+ v8::Script::Compile(v8_str(script3)); |
+ CHECK(try_catch2.HasCaught()); |
+ v8::String::Utf8Value exception(try_catch2.Exception()); |
+ CHECK_EQ(0, |
+ strcmp( |
+ "ReferenceError: In strong mode, using an undeclared global " |
+ "variable 'not_there3' is not allowed", |
+ *exception)); |
+ } |
+} |