Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(766)

Side by Side Diff: test/cctest/test-api.cc

Issue 101733002: Fixed global object leak (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: spacing Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 8506 matching lines...) Expand 10 before | Expand all | Expand 10 after
8517 Local<v8::Object> global2 = env2->Global(); 8517 Local<v8::Object> global2 = env2->Global();
8518 global2->Set(v8_str("prop"), v8::Integer::New(1)); 8518 global2->Set(v8_str("prop"), v8::Integer::New(1));
8519 CompileRun("function getProp() {return prop;}"); 8519 CompileRun("function getProp() {return prop;}");
8520 8520
8521 env1->Global()->Set(v8_str("getProp"), 8521 env1->Global()->Set(v8_str("getProp"),
8522 global2->Get(v8_str("getProp"))); 8522 global2->Get(v8_str("getProp")));
8523 8523
8524 // Detach env2's global, and reuse the global object of env2 8524 // Detach env2's global, and reuse the global object of env2
8525 env2->Exit(); 8525 env2->Exit();
8526 env2->DetachGlobal(); 8526 env2->DetachGlobal();
8527 // env2 has a new global object.
8528 CHECK(!env2->Global()->Equals(global2));
8529 8527
8530 v8::Handle<Context> env3 = Context::New(env1->GetIsolate(), 8528 v8::Handle<Context> env3 = Context::New(env1->GetIsolate(),
8531 0, 8529 0,
8532 v8::Handle<v8::ObjectTemplate>(), 8530 v8::Handle<v8::ObjectTemplate>(),
8533 global2); 8531 global2);
8534 env3->SetSecurityToken(v8_str("bar")); 8532 env3->SetSecurityToken(v8_str("bar"));
8535 env3->Enter(); 8533 env3->Enter();
8536 8534
8537 Local<v8::Object> global3 = env3->Global(); 8535 Local<v8::Object> global3 = env3->Global();
8538 CHECK_EQ(global2, global3); 8536 CHECK_EQ(global2, global3);
(...skipping 14 matching lines...) Expand all
8553 } 8551 }
8554 8552
8555 // Check that env3 is not accessible from env1 8553 // Check that env3 is not accessible from env1
8556 { 8554 {
8557 Local<Value> r = global3->Get(v8_str("prop2")); 8555 Local<Value> r = global3->Get(v8_str("prop2"));
8558 CHECK(r->IsUndefined()); 8556 CHECK(r->IsUndefined());
8559 } 8557 }
8560 } 8558 }
8561 8559
8562 8560
8563 TEST(DetachAndReattachGlobal) { 8561 TEST(DetachGlobal) {
8564 LocalContext env1; 8562 LocalContext env1;
8565 v8::HandleScope scope(env1->GetIsolate()); 8563 v8::HandleScope scope(env1->GetIsolate());
8566 8564
8567 // Create second environment. 8565 // Create second environment.
8568 v8::Handle<Context> env2 = Context::New(env1->GetIsolate()); 8566 v8::Handle<Context> env2 = Context::New(env1->GetIsolate());
8569 8567
8570 Local<Value> foo = v8_str("foo"); 8568 Local<Value> foo = v8_str("foo");
8571 8569
8572 // Set same security token for env1 and env2. 8570 // Set same security token for env1 and env2.
8573 env1->SetSecurityToken(foo); 8571 env1->SetSecurityToken(foo);
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
8618 CHECK_EQ(24, result->Int32Value()); 8616 CHECK_EQ(24, result->Int32Value());
8619 8617
8620 // Change security token for env3 to something different from env1 and env2. 8618 // Change security token for env3 to something different from env1 and env2.
8621 env3->SetSecurityToken(v8_str("bar")); 8619 env3->SetSecurityToken(v8_str("bar"));
8622 8620
8623 // Check that we do not have access to other.p in env1. |other| is now 8621 // Check that we do not have access to other.p in env1. |other| is now
8624 // the global object for env3 which has a different security token, 8622 // the global object for env3 which has a different security token,
8625 // so access should be blocked. 8623 // so access should be blocked.
8626 result = CompileRun("other.p"); 8624 result = CompileRun("other.p");
8627 CHECK(result->IsUndefined()); 8625 CHECK(result->IsUndefined());
8628
8629 // Detach the global for env3 and reattach it to env2.
8630 env3->DetachGlobal();
8631 env2->ReattachGlobal(global2);
8632
8633 // Check that we have access to other.p again in env1. |other| is now
8634 // the global object for env2 which has the same security token as env1.
8635 result = CompileRun("other.p");
8636 CHECK(result->IsInt32());
8637 CHECK_EQ(42, result->Int32Value());
8638 } 8626 }
8639 8627
8640 8628
8629 TEST(DetachedAccesses) {
8630 LocalContext env1;
8631 v8::HandleScope scope(env1->GetIsolate());
8632
8633 // Create second environment.
8634 v8::Handle<Context> env2 = Context::New(env1->GetIsolate());
8635
8636 Local<Value> foo = v8_str("foo");
8637
8638 // Set same security token for env1 and env2.
8639 env1->SetSecurityToken(foo);
8640 env2->SetSecurityToken(foo);
8641
8642 {
8643 v8::Context::Scope scope(env2);
8644 CompileRun(
8645 "var x = 'x';"
8646 "function get_x() { return this.x; }"
8647 "function get_x_w() { return get_x(); }"
8648 "");
8649 env1->Global()->Set(v8_str("get_x"), CompileRun("get_x"));
8650 env1->Global()->Set(v8_str("get_x_w"), CompileRun("get_x_w"));
8651 }
8652
8653 Local<Object> env2_global = env2->Global();
8654 env2_global->TurnOnAccessCheck();
8655 env2->DetachGlobal();
8656
8657 Local<Value> result;
8658 result = CompileRun("get_x()");
8659 CHECK(result->IsUndefined());
8660 result = CompileRun("get_x_w()");
8661 CHECK(result->IsUndefined());
8662
8663 // Reattach env2's proxy
8664 env2 = Context::New(env1->GetIsolate(),
8665 0,
8666 v8::Handle<v8::ObjectTemplate>(),
8667 env2_global);
8668 env2->SetSecurityToken(foo);
8669 {
8670 v8::Context::Scope scope(env2);
8671 CompileRun("var x = 'x2';");
8672 }
8673
8674 result = CompileRun("get_x()");
8675 CHECK(result->IsUndefined());
8676 result = CompileRun("get_x_w()");
8677 CHECK_EQ(v8_str("x2"), result);
8678 }
8679
8680
8641 static bool allowed_access_type[v8::ACCESS_KEYS + 1] = { false }; 8681 static bool allowed_access_type[v8::ACCESS_KEYS + 1] = { false };
8642 static bool NamedAccessBlocker(Local<v8::Object> global, 8682 static bool NamedAccessBlocker(Local<v8::Object> global,
8643 Local<Value> name, 8683 Local<Value> name,
8644 v8::AccessType type, 8684 v8::AccessType type,
8645 Local<Value> data) { 8685 Local<Value> data) {
8646 return CcTest::isolate()->GetCurrentContext()->Global()->Equals(global) || 8686 return CcTest::isolate()->GetCurrentContext()->Global()->Equals(global) ||
8647 allowed_access_type[type]; 8687 allowed_access_type[type];
8648 } 8688 }
8649 8689
8650 8690
(...skipping 5590 matching lines...) Expand 10 before | Expand all | Expand 10 after
14241 CHECK(f2->Call(global, 0, NULL)->Equals(v8_num(1))); 14281 CHECK(f2->Call(global, 0, NULL)->Equals(v8_num(1)));
14242 } 14282 }
14243 14283
14244 // Same for g1 and g2. 14284 // Same for g1 and g2.
14245 CHECK(g1->Call(global, 0, NULL)->Equals(v8_num(1))); 14285 CHECK(g1->Call(global, 0, NULL)->Equals(v8_num(1)));
14246 for (int i = 0; i < 4; i++) { 14286 for (int i = 0; i < 4; i++) {
14247 CHECK(g2->Call(global, 0, NULL)->Equals(v8_num(1))); 14287 CHECK(g2->Call(global, 0, NULL)->Equals(v8_num(1)));
14248 } 14288 }
14249 14289
14250 // Detach the global and turn on access check. 14290 // Detach the global and turn on access check.
14291 Local<Object> hidden_global = Local<Object>::Cast(
14292 context->Global()->GetPrototype());
14251 context->DetachGlobal(); 14293 context->DetachGlobal();
14252 context->Global()->TurnOnAccessCheck(); 14294 hidden_global->TurnOnAccessCheck();
14253 14295
14254 // Failing access check to property get results in undefined. 14296 // Failing access check to property get results in undefined.
14255 CHECK(f1->Call(global, 0, NULL)->IsUndefined()); 14297 CHECK(f1->Call(global, 0, NULL)->IsUndefined());
14256 CHECK(f2->Call(global, 0, NULL)->IsUndefined()); 14298 CHECK(f2->Call(global, 0, NULL)->IsUndefined());
14257 14299
14258 // Failing access check to function call results in exception. 14300 // Failing access check to function call results in exception.
14259 CHECK(g1->Call(global, 0, NULL).IsEmpty()); 14301 CHECK(g1->Call(global, 0, NULL).IsEmpty());
14260 CHECK(g2->Call(global, 0, NULL).IsEmpty()); 14302 CHECK(g2->Call(global, 0, NULL).IsEmpty());
14261 14303
14262 // No failing access check when just returning a constant. 14304 // No failing access check when just returning a constant.
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
14326 } 14368 }
14327 14369
14328 // Same for g1 and g2. 14370 // Same for g1 and g2.
14329 CHECK(g1->Call(global, 0, NULL)->Equals(v8_num(1))); 14371 CHECK(g1->Call(global, 0, NULL)->Equals(v8_num(1)));
14330 for (int i = 0; i < 4; i++) { 14372 for (int i = 0; i < 4; i++) {
14331 CHECK(g2->Call(global, 0, NULL)->Equals(v8_num(1))); 14373 CHECK(g2->Call(global, 0, NULL)->Equals(v8_num(1)));
14332 } 14374 }
14333 14375
14334 // Detach the global and turn on access check now blocking access to property 14376 // Detach the global and turn on access check now blocking access to property
14335 // a and function h. 14377 // a and function h.
14378 Local<Object> hidden_global = Local<Object>::Cast(
14379 context->Global()->GetPrototype());
14336 context->DetachGlobal(); 14380 context->DetachGlobal();
14337 context->Global()->TurnOnAccessCheck(); 14381 hidden_global->TurnOnAccessCheck();
14338 14382
14339 // Failing access check to property get results in undefined. 14383 // Failing access check to property get results in undefined.
14340 CHECK(f1->Call(global, 0, NULL)->IsUndefined()); 14384 CHECK(f1->Call(global, 0, NULL)->IsUndefined());
14341 CHECK(f2->Call(global, 0, NULL)->IsUndefined()); 14385 CHECK(f2->Call(global, 0, NULL)->IsUndefined());
14342 14386
14343 // Failing access check to function call results in exception. 14387 // Failing access check to function call results in exception.
14344 CHECK(g1->Call(global, 0, NULL).IsEmpty()); 14388 CHECK(g1->Call(global, 0, NULL).IsEmpty());
14345 CHECK(g2->Call(global, 0, NULL).IsEmpty()); 14389 CHECK(g2->Call(global, 0, NULL).IsEmpty());
14346 14390
14347 // No failing access check when just returning a constant. 14391 // No failing access check when just returning a constant.
14348 CHECK(h->Call(global, 0, NULL)->Equals(v8_num(1))); 14392 CHECK(h->Call(global, 0, NULL)->Equals(v8_num(1)));
14349 14393
14350 // Now compile the source again. And get the newly compiled functions, except 14394 // Now compile the source again. And get the newly compiled functions, except
14351 // for h for which access is blocked. 14395 // for h for which access is blocked.
14352 CompileRun(source); 14396 CompileRun(source);
14353 f1 = Local<Function>::Cast(context->Global()->Get(v8_str("f1"))); 14397 f1 = Local<Function>::Cast(hidden_global->Get(v8_str("f1")));
14354 f2 = Local<Function>::Cast(context->Global()->Get(v8_str("f2"))); 14398 f2 = Local<Function>::Cast(hidden_global->Get(v8_str("f2")));
14355 g1 = Local<Function>::Cast(context->Global()->Get(v8_str("g1"))); 14399 g1 = Local<Function>::Cast(hidden_global->Get(v8_str("g1")));
14356 g2 = Local<Function>::Cast(context->Global()->Get(v8_str("g2"))); 14400 g2 = Local<Function>::Cast(hidden_global->Get(v8_str("g2")));
14357 CHECK(context->Global()->Get(v8_str("h"))->IsUndefined()); 14401 CHECK(hidden_global->Get(v8_str("h"))->IsUndefined());
14358 14402
14359 // Failing access check to property get results in undefined. 14403 // Failing access check to property get results in undefined.
14360 CHECK(f1->Call(global, 0, NULL)->IsUndefined()); 14404 CHECK(f1->Call(global, 0, NULL)->IsUndefined());
14361 CHECK(f2->Call(global, 0, NULL)->IsUndefined()); 14405 CHECK(f2->Call(global, 0, NULL)->IsUndefined());
14362 14406
14363 // Failing access check to function call results in exception. 14407 // Failing access check to function call results in exception.
14364 CHECK(g1->Call(global, 0, NULL).IsEmpty()); 14408 CHECK(g1->Call(global, 0, NULL).IsEmpty());
14365 CHECK(g2->Call(global, 0, NULL).IsEmpty()); 14409 CHECK(g2->Call(global, 0, NULL).IsEmpty());
14366 } 14410 }
14367 14411
(...skipping 846 matching lines...) Expand 10 before | Expand all | Expand 10 after
15214 v8::Handle<v8::String> foo_string = 15258 v8::Handle<v8::String> foo_string =
15215 v8::String::NewFromUtf8(context->GetIsolate(), "foo"); 15259 v8::String::NewFromUtf8(context->GetIsolate(), "foo");
15216 obj->Set(foo_string, func_templ->GetFunction()); 15260 obj->Set(foo_string, func_templ->GetFunction());
15217 v8::Handle<v8::Object> obj_clone = obj->Clone(); 15261 v8::Handle<v8::Object> obj_clone = obj->Clone();
15218 obj_clone->Set(foo_string, 15262 obj_clone->Set(foo_string,
15219 v8::String::NewFromUtf8(context->GetIsolate(), "Hello")); 15263 v8::String::NewFromUtf8(context->GetIsolate(), "Hello"));
15220 CHECK(!obj->Get(foo_string)->IsUndefined()); 15264 CHECK(!obj->Get(foo_string)->IsUndefined());
15221 } 15265 }
15222 15266
15223 15267
15224 // Regression test for http://crbug.com/16276.
15225 THREADED_TEST(Regress16276) {
15226 LocalContext context;
15227 v8::HandleScope scope(context->GetIsolate());
15228 // Force the IC in f to be a dictionary load IC.
15229 CompileRun("function f(obj) { return obj.x; }\n"
15230 "var obj = { x: { foo: 42 }, y: 87 };\n"
15231 "var x = obj.x;\n"
15232 "delete obj.y;\n"
15233 "for (var i = 0; i < 5; i++) f(obj);");
15234 // Detach the global object to make 'this' refer directly to the
15235 // global object (not the proxy), and make sure that the dictionary
15236 // load IC doesn't mess up loading directly from the global object.
15237 context->DetachGlobal();
15238 CHECK_EQ(42, CompileRun("f(this).foo")->Int32Value());
15239 }
15240
15241 static void CheckElementValue(i::Isolate* isolate, 15268 static void CheckElementValue(i::Isolate* isolate,
15242 int expected, 15269 int expected,
15243 i::Handle<i::Object> obj, 15270 i::Handle<i::Object> obj,
15244 int offset) { 15271 int offset) {
15245 i::Object* element = obj->GetElement(isolate, offset)->ToObjectChecked(); 15272 i::Object* element = obj->GetElement(isolate, offset)->ToObjectChecked();
15246 CHECK_EQ(expected, i::Smi::cast(element)->value()); 15273 CHECK_EQ(expected, i::Smi::cast(element)->value());
15247 } 15274 }
15248 15275
15249 15276
15250 THREADED_TEST(PixelArray) { 15277 THREADED_TEST(PixelArray) {
(...skipping 5621 matching lines...) Expand 10 before | Expand all | Expand 10 after
20872 } 20899 }
20873 for (int i = 0; i < runs; i++) { 20900 for (int i = 0; i < runs; i++) {
20874 Local<String> expected; 20901 Local<String> expected;
20875 if (i != 0) { 20902 if (i != 0) {
20876 CHECK_EQ(v8_str("escape value"), values[i]); 20903 CHECK_EQ(v8_str("escape value"), values[i]);
20877 } else { 20904 } else {
20878 CHECK(values[i].IsEmpty()); 20905 CHECK(values[i].IsEmpty());
20879 } 20906 }
20880 } 20907 }
20881 } 20908 }
OLDNEW
« src/api.cc ('K') | « src/v8natives.js ('k') | test/cctest/test-decls.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698