1 // Copyright 2013 the V8 project authors. All rights reserved. 2 // Redistribution and use in source and binary forms, with or without 3 // modification, are permitted provided that the following conditions are 4 // met: 5 // 6 // * Redistributions of source code must retain the above copyright 7 // notice, this list of conditions and the following disclaimer. 8 // * Redistributions in binary form must reproduce the above 9 // copyright notice, this list of conditions and the following 10 // disclaimer in the documentation and/or other materials provided 11 // with the distribution. 12 // * Neither the name of Google Inc. nor the names of its 13 // contributors may be used to endorse or promote products derived 14 // from this software without specific prior written permission. 15 // 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 28 #include "src/api.h" 29 #include "src/v8.h" 30 #include "test/cctest/cctest.h" 31 32 using ::v8::Array; 33 using ::v8::Context; 34 using ::v8::Local; 35 using ::v8::Value; 36 37 // This test fails if properties on the prototype of the global object appear 38 // as declared globals. 39 TEST(StrictUndeclaredGlobalVariable) { 40 v8::HandleScope scope(CcTest::isolate()); 41 v8::Local<v8::String> var_name = v8_str("x"); 42 LocalContext context; 43 v8::TryCatch try_catch(CcTest::isolate()); 44 v8::Local<v8::Script> script = v8_compile("\"use strict\"; x = 42;"); 45 v8::Local<v8::Object> proto = v8::Object::New(CcTest::isolate()); 46 v8::Local<v8::Object> global = 47 context->Global()->GetPrototype().As<v8::Object>(); 48 proto->Set(context.local(), var_name, v8_num(100)).FromJust(); 49 global->SetPrototype(context.local(), proto).FromJust(); 50 CHECK(script->Run(context.local()).IsEmpty()); 51 CHECK(try_catch.HasCaught()); 52 v8::String::Utf8Value exception(try_catch.Exception()); 53 CHECK_EQ(0, strcmp("ReferenceError: x is not defined", *exception)); 54 } 55 56 57 TEST(KeysGlobalObject_Regress2764) { 58 LocalContext env1; 59 v8::HandleScope scope(env1->GetIsolate()); 60 61 // Create second environment. 62 v8::Local<Context> env2 = Context::New(env1->GetIsolate()); 63 64 Local<Value> token = v8_str("foo"); 65 66 // Set same security token for env1 and env2. 67 env1->SetSecurityToken(token); 68 env2->SetSecurityToken(token); 69 70 // Create a reference to env2 global from env1 global. 71 env1->Global() 72 ->Set(env1.local(), v8_str("global2"), env2->Global()) 73 .FromJust(); 74 // Set some global variables in global2 75 env2->Global()->Set(env2, v8_str("a"), v8_str("a")).FromJust(); 76 env2->Global()->Set(env2, v8_str("42"), v8_str("42")).FromJust(); 77 78 // List all entries from global2. 79 Local<Array> result; 80 result = Local<Array>::Cast(CompileRun("Object.keys(global2)")); 81 CHECK_EQ(2u, result->Length()); 82 CHECK( 83 v8_str("42") 84 ->Equals(env1.local(), result->Get(env1.local(), 0).ToLocalChecked()) 85 .FromJust()); 86 CHECK( 87 v8_str("a") 88 ->Equals(env1.local(), result->Get(env1.local(), 1).ToLocalChecked()) 89 .FromJust()); 90 91 result = 92 Local<Array>::Cast(CompileRun("Object.getOwnPropertyNames(global2)")); 93 CHECK_LT(2u, result->Length()); 94 // Check that all elements are in the property names 95 ExpectTrue("-1 < Object.getOwnPropertyNames(global2).indexOf('42')"); 96 ExpectTrue("-1 < Object.getOwnPropertyNames(global2).indexOf('a')"); 97 98 // Hold on to global from env2 and detach global from env2. 99 env2->DetachGlobal(); 100 101 // List again all entries from the detached global2. 102 result = Local<Array>::Cast(CompileRun("Object.keys(global2)")); 103 CHECK_EQ(0u, result->Length()); 104 result = 105 Local<Array>::Cast(CompileRun("Object.getOwnPropertyNames(global2)")); 106 CHECK_EQ(0u, result->Length()); 107 } 108