| 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 |