OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 } |
OLD | NEW |