diff options
| author | Andrei Popescu <andreip@google.com> | 2010-03-29 12:03:09 +0100 |
|---|---|---|
| committer | Andrei Popescu <andreip@google.com> | 2010-03-29 12:03:09 +0100 |
| commit | 74b3c146906ea120f97974b0e16aec75c17ebf66 (patch) | |
| tree | 529f5893bf30271b7123fa94822c28131bd3bda1 /test | |
| parent | 144045c95df339bcbcf35374401289e1eefc1d85 (diff) | |
| download | android_external_v8-74b3c146906ea120f97974b0e16aec75c17ebf66.tar.gz android_external_v8-74b3c146906ea120f97974b0e16aec75c17ebf66.tar.bz2 android_external_v8-74b3c146906ea120f97974b0e16aec75c17ebf66.zip | |
Cherry pick http://codereview.chromium.org/1207003/show
Implement support for reattaching a global object to a context. This
can be used to use the same global object for different contexts at
different points in time.
Needed to fix b: 2533219
Change-Id: Ib3b0d35f6ce3e0a5f4b8e54561ba2e99a9ab0ab1
Diffstat (limited to 'test')
| -rw-r--r-- | test/cctest/test-api.cc | 83 |
1 files changed, 81 insertions, 2 deletions
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc index db16bfc4..80bc0743 100644 --- a/test/cctest/test-api.cc +++ b/test/cctest/test-api.cc @@ -4350,7 +4350,7 @@ TEST(ContextDetachGlobal) { // Enter env2 env2->Enter(); - // Create a function in env1 + // Create a function in env2 and add a reference to it in env1. Local<v8::Object> global2 = env2->Global(); global2->Set(v8_str("prop"), v8::Integer::New(1)); CompileRun("function getProp() {return prop;}"); @@ -4358,7 +4358,7 @@ TEST(ContextDetachGlobal) { env1->Global()->Set(v8_str("getProp"), global2->Get(v8_str("getProp"))); - // Detach env1's global, and reuse the global object of env1 + // Detach env2's global, and reuse the global object of env2 env2->Exit(); env2->DetachGlobal(); // env2 has a new global object. @@ -4398,6 +4398,85 @@ TEST(ContextDetachGlobal) { } +TEST(DetachAndReattachGlobal) { + v8::HandleScope scope; + LocalContext env1; + + // Create second environment. + v8::Persistent<Context> env2 = Context::New(); + + Local<Value> foo = v8_str("foo"); + + // Set same security token for env1 and env2. + env1->SetSecurityToken(foo); + env2->SetSecurityToken(foo); + + // Create a property on the global object in env2. + { + v8::Context::Scope scope(env2); + env2->Global()->Set(v8_str("p"), v8::Integer::New(42)); + } + + // Create a reference to env2 global from env1 global. + env1->Global()->Set(v8_str("other"), env2->Global()); + + // Check that we have access to other.p in env2 from env1. + Local<Value> result = CompileRun("other.p"); + CHECK(result->IsInt32()); + CHECK_EQ(42, result->Int32Value()); + + // Hold on to global from env2 and detach global from env2. + Local<v8::Object> global2 = env2->Global(); + env2->DetachGlobal(); + + // Check that the global has been detached. No other.p property can + // be found. + result = CompileRun("other.p"); + CHECK(result->IsUndefined()); + + // Reuse global2 for env3. + v8::Persistent<Context> env3 = + Context::New(0, v8::Handle<v8::ObjectTemplate>(), global2); + CHECK_EQ(global2, env3->Global()); + + // Start by using the same security token for env3 as for env1 and env2. + env3->SetSecurityToken(foo); + + // Create a property on the global object in env3. + { + v8::Context::Scope scope(env3); + env3->Global()->Set(v8_str("p"), v8::Integer::New(24)); + } + + // Check that other.p is now the property in env3 and that we have access. + result = CompileRun("other.p"); + CHECK(result->IsInt32()); + CHECK_EQ(24, result->Int32Value()); + + // Change security token for env3 to something different from env1 and env2. + env3->SetSecurityToken(v8_str("bar")); + + // Check that we do not have access to other.p in env1. |other| is now + // the global object for env3 which has a different security token, + // so access should be blocked. + result = CompileRun("other.p"); + CHECK(result->IsUndefined()); + + // Detach the global for env3 and reattach it to env2. + env3->DetachGlobal(); + env2->ReattachGlobal(global2); + + // Check that we have access to other.p again in env1. |other| is now + // the global object for env2 which has the same security token as env1. + result = CompileRun("other.p"); + CHECK(result->IsInt32()); + CHECK_EQ(42, result->Int32Value()); + + env2.Dispose(); + env3.Dispose(); +} + + static bool NamedAccessBlocker(Local<v8::Object> global, Local<Value> name, v8::AccessType type, |
