| 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 7655 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7666 "}"); | 7666 "}"); |
| 7667 CHECK(try_catch.HasCaught()); | 7667 CHECK(try_catch.HasCaught()); |
| 7668 CHECK(!try_catch.Message().IsEmpty()); | 7668 CHECK(!try_catch.Message().IsEmpty()); |
| 7669 String::Utf8Value finally_exception_value(try_catch.Exception()); | 7669 String::Utf8Value finally_exception_value(try_catch.Exception()); |
| 7670 CHECK_EQ(0, strcmp(*finally_exception_value, "2")); | 7670 CHECK_EQ(0, strcmp(*finally_exception_value, "2")); |
| 7671 } | 7671 } |
| 7672 | 7672 |
| 7673 | 7673 |
| 7674 // For use within the TestSecurityHandler() test. | 7674 // For use within the TestSecurityHandler() test. |
| 7675 static bool g_security_callback_result = false; | 7675 static bool g_security_callback_result = false; |
| 7676 static bool NamedSecurityTestCallback(Local<v8::Object> global, | 7676 static bool SecurityTestCallback(Local<v8::Object> global, Local<Value> name, |
| 7677 Local<Value> name, | 7677 v8::AccessType type, Local<Value> data) { |
| 7678 v8::AccessType type, | |
| 7679 Local<Value> data) { | |
| 7680 printf("a\n"); | 7678 printf("a\n"); |
| 7681 // Always allow read access. | |
| 7682 if (type == v8::ACCESS_GET) | |
| 7683 return true; | |
| 7684 | |
| 7685 // Sometimes allow other access. | |
| 7686 return g_security_callback_result; | 7679 return g_security_callback_result; |
| 7687 } | 7680 } |
| 7688 | 7681 |
| 7689 | |
| 7690 static bool IndexedSecurityTestCallback(Local<v8::Object> global, | |
| 7691 uint32_t key, | |
| 7692 v8::AccessType type, | |
| 7693 Local<Value> data) { | |
| 7694 printf("b\n"); | |
| 7695 // Always allow read access. | |
| 7696 if (type == v8::ACCESS_GET) | |
| 7697 return true; | |
| 7698 | |
| 7699 // Sometimes allow other access. | |
| 7700 return g_security_callback_result; | |
| 7701 } | |
| 7702 | |
| 7703 | 7682 |
| 7704 // SecurityHandler can't be run twice | 7683 // SecurityHandler can't be run twice |
| 7705 TEST(SecurityHandler) { | 7684 TEST(SecurityHandler) { |
| 7706 v8::Isolate* isolate = CcTest::isolate(); | 7685 v8::Isolate* isolate = CcTest::isolate(); |
| 7707 v8::HandleScope scope0(isolate); | 7686 v8::HandleScope scope0(isolate); |
| 7708 v8::Handle<v8::ObjectTemplate> global_template = | 7687 v8::Handle<v8::ObjectTemplate> global_template = |
| 7709 v8::ObjectTemplate::New(isolate); | 7688 v8::ObjectTemplate::New(isolate); |
| 7710 global_template->SetAccessCheckCallbacks(NamedSecurityTestCallback, | 7689 global_template->SetAccessCheckCallbacks(SecurityTestCallback, NULL); |
| 7711 IndexedSecurityTestCallback); | |
| 7712 // Create an environment | 7690 // Create an environment |
| 7713 v8::Handle<Context> context0 = Context::New(isolate, NULL, global_template); | 7691 v8::Handle<Context> context0 = Context::New(isolate, NULL, global_template); |
| 7714 context0->Enter(); | 7692 context0->Enter(); |
| 7715 | 7693 |
| 7716 v8::Handle<v8::Object> global0 = context0->Global(); | 7694 v8::Handle<v8::Object> global0 = context0->Global(); |
| 7717 v8::Handle<Script> script0 = v8_compile("foo = 111"); | 7695 v8::Handle<Script> script0 = v8_compile("foo = 111"); |
| 7718 script0->Run(); | 7696 script0->Run(); |
| 7719 global0->Set(v8_str("0"), v8_num(999)); | 7697 global0->Set(v8_str("0"), v8_num(999)); |
| 7720 v8::Handle<Value> foo0 = global0->Get(v8_str("foo")); | 7698 v8::Handle<Value> foo0 = global0->Get(v8_str("foo")); |
| 7721 CHECK_EQ(111, foo0->Int32Value()); | 7699 CHECK_EQ(111, foo0->Int32Value()); |
| 7722 v8::Handle<Value> z0 = global0->Get(v8_str("0")); | 7700 v8::Handle<Value> z0 = global0->Get(v8_str("0")); |
| 7723 CHECK_EQ(999, z0->Int32Value()); | 7701 CHECK_EQ(999, z0->Int32Value()); |
| 7724 | 7702 |
| 7725 // Create another environment, should fail security checks. | 7703 // Create another environment, should fail security checks. |
| 7726 v8::HandleScope scope1(isolate); | 7704 v8::HandleScope scope1(isolate); |
| 7727 | 7705 |
| 7728 v8::Handle<Context> context1 = | 7706 v8::Handle<Context> context1 = |
| 7729 Context::New(isolate, NULL, global_template); | 7707 Context::New(isolate, NULL, global_template); |
| 7730 context1->Enter(); | 7708 context1->Enter(); |
| 7731 | 7709 |
| 7732 v8::Handle<v8::Object> global1 = context1->Global(); | 7710 v8::Handle<v8::Object> global1 = context1->Global(); |
| 7733 global1->Set(v8_str("othercontext"), global0); | 7711 global1->Set(v8_str("othercontext"), global0); |
| 7734 // This set will fail the security check. | 7712 // This set will fail the security check. |
| 7735 v8::Handle<Script> script1 = | 7713 v8::Handle<Script> script1 = |
| 7736 v8_compile("othercontext.foo = 222; othercontext[0] = 888;"); | 7714 v8_compile("othercontext.foo = 222; othercontext[0] = 888;"); |
| 7737 script1->Run(); | 7715 script1->Run(); |
| 7716 g_security_callback_result = true; |
| 7738 // This read will pass the security check. | 7717 // This read will pass the security check. |
| 7739 v8::Handle<Value> foo1 = global0->Get(v8_str("foo")); | 7718 v8::Handle<Value> foo1 = global0->Get(v8_str("foo")); |
| 7740 CHECK_EQ(111, foo1->Int32Value()); | 7719 CHECK_EQ(111, foo1->Int32Value()); |
| 7741 // This read will pass the security check. | 7720 // This read will pass the security check. |
| 7742 v8::Handle<Value> z1 = global0->Get(v8_str("0")); | 7721 v8::Handle<Value> z1 = global0->Get(v8_str("0")); |
| 7743 CHECK_EQ(999, z1->Int32Value()); | 7722 CHECK_EQ(999, z1->Int32Value()); |
| 7744 | 7723 |
| 7745 // Create another environment, should pass security checks. | 7724 // Create another environment, should pass security checks. |
| 7746 { g_security_callback_result = true; // allow security handler to pass. | 7725 { |
| 7747 v8::HandleScope scope2(isolate); | 7726 v8::HandleScope scope2(isolate); |
| 7748 LocalContext context2; | 7727 LocalContext context2; |
| 7749 v8::Handle<v8::Object> global2 = context2->Global(); | 7728 v8::Handle<v8::Object> global2 = context2->Global(); |
| 7750 global2->Set(v8_str("othercontext"), global0); | 7729 global2->Set(v8_str("othercontext"), global0); |
| 7751 v8::Handle<Script> script2 = | 7730 v8::Handle<Script> script2 = |
| 7752 v8_compile("othercontext.foo = 333; othercontext[0] = 888;"); | 7731 v8_compile("othercontext.foo = 333; othercontext[0] = 888;"); |
| 7753 script2->Run(); | 7732 script2->Run(); |
| 7754 v8::Handle<Value> foo2 = global0->Get(v8_str("foo")); | 7733 v8::Handle<Value> foo2 = global0->Get(v8_str("foo")); |
| 7755 CHECK_EQ(333, foo2->Int32Value()); | 7734 CHECK_EQ(333, foo2->Int32Value()); |
| 7756 v8::Handle<Value> z2 = global0->Get(v8_str("0")); | 7735 v8::Handle<Value> z2 = global0->Get(v8_str("0")); |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7859 // gets stopped by the security checks on the other global object. | 7838 // gets stopped by the security checks on the other global object. |
| 7860 Local<Script> access_f2 = v8_compile("f.foo"); | 7839 Local<Script> access_f2 = v8_compile("f.foo"); |
| 7861 Local<Script> access_f3 = v8_compile("f[99]"); | 7840 Local<Script> access_f3 = v8_compile("f[99]"); |
| 7862 for (int k = 0; k < 5; k++) { | 7841 for (int k = 0; k < 5; k++) { |
| 7863 CHECK(access_f2->Run().IsEmpty()); | 7842 CHECK(access_f2->Run().IsEmpty()); |
| 7864 CHECK(access_f3->Run().IsEmpty()); | 7843 CHECK(access_f3->Run().IsEmpty()); |
| 7865 } | 7844 } |
| 7866 } | 7845 } |
| 7867 | 7846 |
| 7868 | 7847 |
| 7869 static bool named_security_check_with_gc_called; | 7848 static bool security_check_with_gc_called; |
| 7870 | 7849 |
| 7871 static bool NamedSecurityCallbackWithGC(Local<v8::Object> global, | 7850 static bool SecurityTestCallbackWithGC(Local<v8::Object> global, |
| 7872 Local<Value> name, | 7851 Local<v8::Value> name, |
| 7873 v8::AccessType type, | 7852 v8::AccessType type, Local<Value> data) { |
| 7874 Local<Value> data) { | |
| 7875 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); | 7853 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 7876 named_security_check_with_gc_called = true; | 7854 security_check_with_gc_called = true; |
| 7877 return true; | 7855 return true; |
| 7878 } | 7856 } |
| 7879 | 7857 |
| 7880 | |
| 7881 static bool indexed_security_check_with_gc_called; | |
| 7882 | |
| 7883 static bool IndexedSecurityTestCallbackWithGC(Local<v8::Object> global, | |
| 7884 uint32_t key, | |
| 7885 v8::AccessType type, | |
| 7886 Local<Value> data) { | |
| 7887 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); | |
| 7888 indexed_security_check_with_gc_called = true; | |
| 7889 return true; | |
| 7890 } | |
| 7891 | |
| 7892 | 7858 |
| 7893 TEST(SecurityTestGCAllowed) { | 7859 TEST(SecurityTestGCAllowed) { |
| 7894 v8::Isolate* isolate = CcTest::isolate(); | 7860 v8::Isolate* isolate = CcTest::isolate(); |
| 7895 v8::HandleScope handle_scope(isolate); | 7861 v8::HandleScope handle_scope(isolate); |
| 7896 v8::Handle<v8::ObjectTemplate> object_template = | 7862 v8::Handle<v8::ObjectTemplate> object_template = |
| 7897 v8::ObjectTemplate::New(isolate); | 7863 v8::ObjectTemplate::New(isolate); |
| 7898 object_template->SetAccessCheckCallbacks(NamedSecurityCallbackWithGC, | 7864 object_template->SetAccessCheckCallbacks(SecurityTestCallbackWithGC, NULL); |
| 7899 IndexedSecurityTestCallbackWithGC); | |
| 7900 | 7865 |
| 7901 v8::Handle<Context> context = Context::New(isolate); | 7866 v8::Handle<Context> context = Context::New(isolate); |
| 7902 v8::Context::Scope context_scope(context); | 7867 v8::Context::Scope context_scope(context); |
| 7903 | 7868 |
| 7904 context->Global()->Set(v8_str("obj"), object_template->NewInstance()); | 7869 context->Global()->Set(v8_str("obj"), object_template->NewInstance()); |
| 7905 | 7870 |
| 7906 named_security_check_with_gc_called = false; | 7871 security_check_with_gc_called = false; |
| 7907 CompileRun("obj.foo = new String(1001);"); | 7872 CompileRun("obj[0] = new String(1002);"); |
| 7908 CHECK(named_security_check_with_gc_called); | 7873 CHECK(security_check_with_gc_called); |
| 7909 | 7874 |
| 7910 indexed_security_check_with_gc_called = false; | 7875 security_check_with_gc_called = false; |
| 7911 CompileRun("obj[0] = new String(1002);"); | |
| 7912 CHECK(indexed_security_check_with_gc_called); | |
| 7913 | |
| 7914 named_security_check_with_gc_called = false; | |
| 7915 CHECK(CompileRun("obj.foo")->ToString(isolate)->Equals(v8_str("1001"))); | |
| 7916 CHECK(named_security_check_with_gc_called); | |
| 7917 | |
| 7918 indexed_security_check_with_gc_called = false; | |
| 7919 CHECK(CompileRun("obj[0]")->ToString(isolate)->Equals(v8_str("1002"))); | 7876 CHECK(CompileRun("obj[0]")->ToString(isolate)->Equals(v8_str("1002"))); |
| 7920 CHECK(indexed_security_check_with_gc_called); | 7877 CHECK(security_check_with_gc_called); |
| 7921 } | 7878 } |
| 7922 | 7879 |
| 7923 | 7880 |
| 7924 THREADED_TEST(CrossDomainDelete) { | 7881 THREADED_TEST(CrossDomainDelete) { |
| 7925 LocalContext env1; | 7882 LocalContext env1; |
| 7926 v8::HandleScope handle_scope(env1->GetIsolate()); | 7883 v8::HandleScope handle_scope(env1->GetIsolate()); |
| 7927 v8::Handle<Context> env2 = Context::New(env1->GetIsolate()); | 7884 v8::Handle<Context> env2 = Context::New(env1->GetIsolate()); |
| 7928 | 7885 |
| 7929 Local<Value> foo = v8_str("foo"); | 7886 Local<Value> foo = v8_str("foo"); |
| 7930 Local<Value> bar = v8_str("bar"); | 7887 Local<Value> bar = v8_str("bar"); |
| (...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8268 CHECK_EQ(16u, results->Length()); | 8225 CHECK_EQ(16u, results->Length()); |
| 8269 for (int i = 0; i < 16; i += 4) { | 8226 for (int i = 0; i < 16; i += 4) { |
| 8270 CHECK(v8_str("env2_x")->Equals(results->Get(i + 0))); | 8227 CHECK(v8_str("env2_x")->Equals(results->Get(i + 0))); |
| 8271 CHECK(v8_str("env1_x")->Equals(results->Get(i + 1))); | 8228 CHECK(v8_str("env1_x")->Equals(results->Get(i + 1))); |
| 8272 CHECK(v8_str("env3_x")->Equals(results->Get(i + 2))); | 8229 CHECK(v8_str("env3_x")->Equals(results->Get(i + 2))); |
| 8273 CHECK(v8_str("env2_x")->Equals(results->Get(i + 3))); | 8230 CHECK(v8_str("env2_x")->Equals(results->Get(i + 3))); |
| 8274 } | 8231 } |
| 8275 } | 8232 } |
| 8276 | 8233 |
| 8277 | 8234 |
| 8278 static bool allowed_access_type[v8::ACCESS_KEYS + 1] = { false }; | 8235 static bool allowed_access = false; |
| 8279 static bool NamedAccessBlocker(Local<v8::Object> global, | 8236 static bool AccessBlocker(Local<v8::Object> global, Local<Value> name, |
| 8280 Local<Value> name, | 8237 v8::AccessType type, Local<Value> data) { |
| 8281 v8::AccessType type, | |
| 8282 Local<Value> data) { | |
| 8283 return CcTest::isolate()->GetCurrentContext()->Global()->Equals(global) || | 8238 return CcTest::isolate()->GetCurrentContext()->Global()->Equals(global) || |
| 8284 allowed_access_type[type]; | 8239 allowed_access; |
| 8285 } | 8240 } |
| 8286 | 8241 |
| 8287 | 8242 |
| 8288 static bool IndexedAccessBlocker(Local<v8::Object> global, | |
| 8289 uint32_t key, | |
| 8290 v8::AccessType type, | |
| 8291 Local<Value> data) { | |
| 8292 return CcTest::isolate()->GetCurrentContext()->Global()->Equals(global) || | |
| 8293 allowed_access_type[type]; | |
| 8294 } | |
| 8295 | |
| 8296 | |
| 8297 static int g_echo_value = -1; | 8243 static int g_echo_value = -1; |
| 8298 | 8244 |
| 8299 | 8245 |
| 8300 static void EchoGetter( | 8246 static void EchoGetter( |
| 8301 Local<String> name, | 8247 Local<String> name, |
| 8302 const v8::PropertyCallbackInfo<v8::Value>& info) { | 8248 const v8::PropertyCallbackInfo<v8::Value>& info) { |
| 8303 info.GetReturnValue().Set(v8_num(g_echo_value)); | 8249 info.GetReturnValue().Set(v8_num(g_echo_value)); |
| 8304 } | 8250 } |
| 8305 | 8251 |
| 8306 | 8252 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 8331 CHECK(false); // This function should not be called.. | 8277 CHECK(false); // This function should not be called.. |
| 8332 } | 8278 } |
| 8333 | 8279 |
| 8334 | 8280 |
| 8335 TEST(AccessControl) { | 8281 TEST(AccessControl) { |
| 8336 v8::Isolate* isolate = CcTest::isolate(); | 8282 v8::Isolate* isolate = CcTest::isolate(); |
| 8337 v8::HandleScope handle_scope(isolate); | 8283 v8::HandleScope handle_scope(isolate); |
| 8338 v8::Handle<v8::ObjectTemplate> global_template = | 8284 v8::Handle<v8::ObjectTemplate> global_template = |
| 8339 v8::ObjectTemplate::New(isolate); | 8285 v8::ObjectTemplate::New(isolate); |
| 8340 | 8286 |
| 8341 global_template->SetAccessCheckCallbacks(NamedAccessBlocker, | 8287 global_template->SetAccessCheckCallbacks(AccessBlocker, NULL); |
| 8342 IndexedAccessBlocker); | |
| 8343 | 8288 |
| 8344 // Add an accessor accessible by cross-domain JS code. | 8289 // Add an accessor accessible by cross-domain JS code. |
| 8345 global_template->SetAccessor( | 8290 global_template->SetAccessor( |
| 8346 v8_str("accessible_prop"), | 8291 v8_str("accessible_prop"), |
| 8347 EchoGetter, EchoSetter, | 8292 EchoGetter, EchoSetter, |
| 8348 v8::Handle<Value>(), | 8293 v8::Handle<Value>(), |
| 8349 v8::AccessControl(v8::ALL_CAN_READ | v8::ALL_CAN_WRITE)); | 8294 v8::AccessControl(v8::ALL_CAN_READ | v8::ALL_CAN_WRITE)); |
| 8350 | 8295 |
| 8351 | 8296 |
| 8352 // Add an accessor that is not accessible by cross-domain JS code. | 8297 // Add an accessor that is not accessible by cross-domain JS code. |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8406 CHECK( | 8351 CHECK( |
| 8407 CompileRun("propertyIsEnumerable.call(other, 'blocked_prop')").IsEmpty()); | 8352 CompileRun("propertyIsEnumerable.call(other, 'blocked_prop')").IsEmpty()); |
| 8408 | 8353 |
| 8409 // Access blocked element. | 8354 // Access blocked element. |
| 8410 CHECK(CompileRun("other[239] = 1").IsEmpty()); | 8355 CHECK(CompileRun("other[239] = 1").IsEmpty()); |
| 8411 | 8356 |
| 8412 CHECK(CompileRun("other[239]").IsEmpty()); | 8357 CHECK(CompileRun("other[239]").IsEmpty()); |
| 8413 CHECK(CompileRun("Object.getOwnPropertyDescriptor(other, '239')").IsEmpty()); | 8358 CHECK(CompileRun("Object.getOwnPropertyDescriptor(other, '239')").IsEmpty()); |
| 8414 CHECK(CompileRun("propertyIsEnumerable.call(other, '239')").IsEmpty()); | 8359 CHECK(CompileRun("propertyIsEnumerable.call(other, '239')").IsEmpty()); |
| 8415 | 8360 |
| 8416 // Enable ACCESS_HAS | 8361 allowed_access = true; |
| 8417 allowed_access_type[v8::ACCESS_HAS] = true; | 8362 // Now we can enumerate the property. |
| 8418 CHECK(CompileRun("other[239]").IsEmpty()); | |
| 8419 // ... and now we can get the descriptor... | |
| 8420 CHECK(CompileRun("Object.getOwnPropertyDescriptor(other, '239').value") | |
| 8421 .IsEmpty()); | |
| 8422 // ... and enumerate the property. | |
| 8423 ExpectTrue("propertyIsEnumerable.call(other, '239')"); | 8363 ExpectTrue("propertyIsEnumerable.call(other, '239')"); |
| 8424 allowed_access_type[v8::ACCESS_HAS] = false; | 8364 allowed_access = false; |
| 8425 | 8365 |
| 8426 // Access a property with JS accessor. | 8366 // Access a property with JS accessor. |
| 8427 CHECK(CompileRun("other.js_accessor_p = 2").IsEmpty()); | 8367 CHECK(CompileRun("other.js_accessor_p = 2").IsEmpty()); |
| 8428 | 8368 |
| 8429 CHECK(CompileRun("other.js_accessor_p").IsEmpty()); | 8369 CHECK(CompileRun("other.js_accessor_p").IsEmpty()); |
| 8430 CHECK(CompileRun("Object.getOwnPropertyDescriptor(other, 'js_accessor_p')") | 8370 CHECK(CompileRun("Object.getOwnPropertyDescriptor(other, 'js_accessor_p')") |
| 8431 .IsEmpty()); | 8371 .IsEmpty()); |
| 8432 | 8372 |
| 8433 // Enable both ACCESS_HAS and ACCESS_GET. | 8373 allowed_access = true; |
| 8434 allowed_access_type[v8::ACCESS_HAS] = true; | |
| 8435 allowed_access_type[v8::ACCESS_GET] = true; | |
| 8436 | 8374 |
| 8437 ExpectString("other.js_accessor_p", "getter"); | 8375 ExpectString("other.js_accessor_p", "getter"); |
| 8438 ExpectObject( | 8376 ExpectObject( |
| 8439 "Object.getOwnPropertyDescriptor(other, 'js_accessor_p').get", getter); | 8377 "Object.getOwnPropertyDescriptor(other, 'js_accessor_p').get", getter); |
| 8440 ExpectObject( | 8378 ExpectObject( |
| 8441 "Object.getOwnPropertyDescriptor(other, 'js_accessor_p').set", setter); | 8379 "Object.getOwnPropertyDescriptor(other, 'js_accessor_p').set", setter); |
| 8442 ExpectUndefined( | 8380 ExpectUndefined( |
| 8443 "Object.getOwnPropertyDescriptor(other, 'js_accessor_p').value"); | 8381 "Object.getOwnPropertyDescriptor(other, 'js_accessor_p').value"); |
| 8444 | 8382 |
| 8445 allowed_access_type[v8::ACCESS_HAS] = false; | 8383 allowed_access = false; |
| 8446 allowed_access_type[v8::ACCESS_GET] = false; | |
| 8447 | 8384 |
| 8448 // Access an element with JS accessor. | 8385 // Access an element with JS accessor. |
| 8449 CHECK(CompileRun("other[42] = 2").IsEmpty()); | 8386 CHECK(CompileRun("other[42] = 2").IsEmpty()); |
| 8450 | 8387 |
| 8451 CHECK(CompileRun("other[42]").IsEmpty()); | 8388 CHECK(CompileRun("other[42]").IsEmpty()); |
| 8452 CHECK(CompileRun("Object.getOwnPropertyDescriptor(other, '42')").IsEmpty()); | 8389 CHECK(CompileRun("Object.getOwnPropertyDescriptor(other, '42')").IsEmpty()); |
| 8453 | 8390 |
| 8454 // Enable both ACCESS_HAS and ACCESS_GET. | 8391 allowed_access = true; |
| 8455 allowed_access_type[v8::ACCESS_HAS] = true; | |
| 8456 allowed_access_type[v8::ACCESS_GET] = true; | |
| 8457 | 8392 |
| 8458 ExpectString("other[42]", "el_getter"); | 8393 ExpectString("other[42]", "el_getter"); |
| 8459 ExpectObject("Object.getOwnPropertyDescriptor(other, '42').get", el_getter); | 8394 ExpectObject("Object.getOwnPropertyDescriptor(other, '42').get", el_getter); |
| 8460 ExpectObject("Object.getOwnPropertyDescriptor(other, '42').set", el_setter); | 8395 ExpectObject("Object.getOwnPropertyDescriptor(other, '42').set", el_setter); |
| 8461 ExpectUndefined("Object.getOwnPropertyDescriptor(other, '42').value"); | 8396 ExpectUndefined("Object.getOwnPropertyDescriptor(other, '42').value"); |
| 8462 | 8397 |
| 8463 allowed_access_type[v8::ACCESS_HAS] = false; | 8398 allowed_access = false; |
| 8464 allowed_access_type[v8::ACCESS_GET] = false; | |
| 8465 | 8399 |
| 8466 v8::Handle<Value> value; | 8400 v8::Handle<Value> value; |
| 8467 | 8401 |
| 8468 // Access accessible property | 8402 // Access accessible property |
| 8469 value = CompileRun("other.accessible_prop = 3"); | 8403 value = CompileRun("other.accessible_prop = 3"); |
| 8470 CHECK(value->IsNumber()); | 8404 CHECK(value->IsNumber()); |
| 8471 CHECK_EQ(3, value->Int32Value()); | 8405 CHECK_EQ(3, value->Int32Value()); |
| 8472 CHECK_EQ(3, g_echo_value); | 8406 CHECK_EQ(3, g_echo_value); |
| 8473 | 8407 |
| 8474 value = CompileRun("other.accessible_prop"); | 8408 value = CompileRun("other.accessible_prop"); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8507 context0->Exit(); | 8441 context0->Exit(); |
| 8508 } | 8442 } |
| 8509 | 8443 |
| 8510 | 8444 |
| 8511 TEST(AccessControlES5) { | 8445 TEST(AccessControlES5) { |
| 8512 v8::Isolate* isolate = CcTest::isolate(); | 8446 v8::Isolate* isolate = CcTest::isolate(); |
| 8513 v8::HandleScope handle_scope(isolate); | 8447 v8::HandleScope handle_scope(isolate); |
| 8514 v8::Handle<v8::ObjectTemplate> global_template = | 8448 v8::Handle<v8::ObjectTemplate> global_template = |
| 8515 v8::ObjectTemplate::New(isolate); | 8449 v8::ObjectTemplate::New(isolate); |
| 8516 | 8450 |
| 8517 global_template->SetAccessCheckCallbacks(NamedAccessBlocker, | 8451 global_template->SetAccessCheckCallbacks(AccessBlocker, NULL); |
| 8518 IndexedAccessBlocker); | |
| 8519 | 8452 |
| 8520 // Add accessible accessor. | 8453 // Add accessible accessor. |
| 8521 global_template->SetAccessor( | 8454 global_template->SetAccessor( |
| 8522 v8_str("accessible_prop"), | 8455 v8_str("accessible_prop"), |
| 8523 EchoGetter, EchoSetter, | 8456 EchoGetter, EchoSetter, |
| 8524 v8::Handle<Value>(), | 8457 v8::Handle<Value>(), |
| 8525 v8::AccessControl(v8::ALL_CAN_READ | v8::ALL_CAN_WRITE)); | 8458 v8::AccessControl(v8::ALL_CAN_READ | v8::ALL_CAN_WRITE)); |
| 8526 | 8459 |
| 8527 | 8460 |
| 8528 // Add an accessor that is not accessible by cross-domain JS code. | 8461 // Add an accessor that is not accessible by cross-domain JS code. |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8571 CompileRun("other.accessible_prop = 42"); | 8504 CompileRun("other.accessible_prop = 42"); |
| 8572 CHECK_EQ(42, g_echo_value); | 8505 CHECK_EQ(42, g_echo_value); |
| 8573 | 8506 |
| 8574 v8::Handle<Value> value; | 8507 v8::Handle<Value> value; |
| 8575 CompileRun("Object.defineProperty(other, 'accessible_prop', {value: -1})"); | 8508 CompileRun("Object.defineProperty(other, 'accessible_prop', {value: -1})"); |
| 8576 value = CompileRun("other.accessible_prop == 42"); | 8509 value = CompileRun("other.accessible_prop == 42"); |
| 8577 CHECK(value->IsTrue()); | 8510 CHECK(value->IsTrue()); |
| 8578 } | 8511 } |
| 8579 | 8512 |
| 8580 | 8513 |
| 8581 static bool BlockEverythingNamed(Local<v8::Object> object, Local<Value> name, | 8514 static bool AccessAlwaysBlocked(Local<v8::Object> global, Local<Value> name, |
| 8582 v8::AccessType type, Local<Value> data) { | 8515 v8::AccessType type, Local<Value> data) { |
| 8516 i::PrintF("Access blocked.\n"); |
| 8583 return false; | 8517 return false; |
| 8584 } | 8518 } |
| 8585 | 8519 |
| 8586 | |
| 8587 static bool BlockEverythingIndexed(Local<v8::Object> object, uint32_t key, | |
| 8588 v8::AccessType type, Local<Value> data) { | |
| 8589 return false; | |
| 8590 } | |
| 8591 | |
| 8592 | 8520 |
| 8593 THREADED_TEST(AccessControlGetOwnPropertyNames) { | 8521 THREADED_TEST(AccessControlGetOwnPropertyNames) { |
| 8594 v8::Isolate* isolate = CcTest::isolate(); | 8522 v8::Isolate* isolate = CcTest::isolate(); |
| 8595 v8::HandleScope handle_scope(isolate); | 8523 v8::HandleScope handle_scope(isolate); |
| 8596 v8::Handle<v8::ObjectTemplate> obj_template = | 8524 v8::Handle<v8::ObjectTemplate> obj_template = |
| 8597 v8::ObjectTemplate::New(isolate); | 8525 v8::ObjectTemplate::New(isolate); |
| 8598 | 8526 |
| 8599 obj_template->Set(v8_str("x"), v8::Integer::New(isolate, 42)); | 8527 obj_template->Set(v8_str("x"), v8::Integer::New(isolate, 42)); |
| 8600 obj_template->SetAccessCheckCallbacks(BlockEverythingNamed, | 8528 obj_template->SetAccessCheckCallbacks(AccessAlwaysBlocked, NULL); |
| 8601 BlockEverythingIndexed); | |
| 8602 | 8529 |
| 8603 // Create an environment | 8530 // Create an environment |
| 8604 v8::Local<Context> context0 = Context::New(isolate, NULL, obj_template); | 8531 v8::Local<Context> context0 = Context::New(isolate, NULL, obj_template); |
| 8605 context0->Enter(); | 8532 context0->Enter(); |
| 8606 | 8533 |
| 8607 v8::Handle<v8::Object> global0 = context0->Global(); | 8534 v8::Handle<v8::Object> global0 = context0->Global(); |
| 8608 | 8535 |
| 8609 v8::HandleScope scope1(CcTest::isolate()); | 8536 v8::HandleScope scope1(CcTest::isolate()); |
| 8610 | 8537 |
| 8611 v8::Local<Context> context1 = Context::New(isolate); | 8538 v8::Local<Context> context1 = Context::New(isolate); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 8634 | 8561 |
| 8635 | 8562 |
| 8636 TEST(SuperAccessControl) { | 8563 TEST(SuperAccessControl) { |
| 8637 i::FLAG_allow_natives_syntax = true; | 8564 i::FLAG_allow_natives_syntax = true; |
| 8638 i::FLAG_harmony_classes = true; | 8565 i::FLAG_harmony_classes = true; |
| 8639 i::FLAG_harmony_object_literals = true; | 8566 i::FLAG_harmony_object_literals = true; |
| 8640 v8::Isolate* isolate = CcTest::isolate(); | 8567 v8::Isolate* isolate = CcTest::isolate(); |
| 8641 v8::HandleScope handle_scope(isolate); | 8568 v8::HandleScope handle_scope(isolate); |
| 8642 v8::Handle<v8::ObjectTemplate> obj_template = | 8569 v8::Handle<v8::ObjectTemplate> obj_template = |
| 8643 v8::ObjectTemplate::New(isolate); | 8570 v8::ObjectTemplate::New(isolate); |
| 8644 obj_template->SetAccessCheckCallbacks(BlockEverythingNamed, | 8571 obj_template->SetAccessCheckCallbacks(AccessAlwaysBlocked, NULL); |
| 8645 BlockEverythingIndexed); | |
| 8646 LocalContext env; | 8572 LocalContext env; |
| 8647 env->Global()->Set(v8_str("prohibited"), obj_template->NewInstance()); | 8573 env->Global()->Set(v8_str("prohibited"), obj_template->NewInstance()); |
| 8648 | 8574 |
| 8649 { | 8575 { |
| 8650 v8::TryCatch try_catch; | 8576 v8::TryCatch try_catch; |
| 8651 CompileRun( | 8577 CompileRun( |
| 8652 "var f = { m() { return super.hasOwnProperty; } }.m;" | 8578 "var f = { m() { return super.hasOwnProperty; } }.m;" |
| 8653 "var m = %ToMethod(f, prohibited);" | 8579 "var m = %ToMethod(f, prohibited);" |
| 8654 "m();"); | 8580 "m();"); |
| 8655 CHECK(try_catch.HasCaught()); | 8581 CHECK(try_catch.HasCaught()); |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8742 CHECK_EQ(10, value->Int32Value()); | 8668 CHECK_EQ(10, value->Int32Value()); |
| 8743 | 8669 |
| 8744 value = v8_compile("other.unreachable")->Run(); | 8670 value = v8_compile("other.unreachable")->Run(); |
| 8745 CHECK(value.IsEmpty()); | 8671 CHECK(value.IsEmpty()); |
| 8746 | 8672 |
| 8747 context1->Exit(); | 8673 context1->Exit(); |
| 8748 context0->Exit(); | 8674 context0->Exit(); |
| 8749 } | 8675 } |
| 8750 | 8676 |
| 8751 | 8677 |
| 8752 static int named_access_count = 0; | 8678 static int access_count = 0; |
| 8753 static int indexed_access_count = 0; | |
| 8754 | 8679 |
| 8755 static bool NamedAccessCounter(Local<v8::Object> global, | 8680 static bool AccessCounter(Local<v8::Object> global, Local<Value> name, |
| 8756 Local<Value> name, | 8681 v8::AccessType type, Local<Value> data) { |
| 8757 v8::AccessType type, | 8682 access_count++; |
| 8758 Local<Value> data) { | |
| 8759 named_access_count++; | |
| 8760 return true; | |
| 8761 } | |
| 8762 | |
| 8763 | |
| 8764 static bool IndexedAccessCounter(Local<v8::Object> global, | |
| 8765 uint32_t key, | |
| 8766 v8::AccessType type, | |
| 8767 Local<Value> data) { | |
| 8768 indexed_access_count++; | |
| 8769 return true; | 8683 return true; |
| 8770 } | 8684 } |
| 8771 | 8685 |
| 8772 | 8686 |
| 8773 // This one is too easily disturbed by other tests. | 8687 // This one is too easily disturbed by other tests. |
| 8774 TEST(AccessControlIC) { | 8688 TEST(AccessControlIC) { |
| 8775 named_access_count = 0; | 8689 access_count = 0; |
| 8776 indexed_access_count = 0; | |
| 8777 | 8690 |
| 8778 v8::Isolate* isolate = CcTest::isolate(); | 8691 v8::Isolate* isolate = CcTest::isolate(); |
| 8779 v8::HandleScope handle_scope(isolate); | 8692 v8::HandleScope handle_scope(isolate); |
| 8780 | 8693 |
| 8781 // Create an environment. | 8694 // Create an environment. |
| 8782 v8::Local<Context> context0 = Context::New(isolate); | 8695 v8::Local<Context> context0 = Context::New(isolate); |
| 8783 context0->Enter(); | 8696 context0->Enter(); |
| 8784 | 8697 |
| 8785 // Create an object that requires access-check functions to be | 8698 // Create an object that requires access-check functions to be |
| 8786 // called for cross-domain access. | 8699 // called for cross-domain access. |
| 8787 v8::Handle<v8::ObjectTemplate> object_template = | 8700 v8::Handle<v8::ObjectTemplate> object_template = |
| 8788 v8::ObjectTemplate::New(isolate); | 8701 v8::ObjectTemplate::New(isolate); |
| 8789 object_template->SetAccessCheckCallbacks(NamedAccessCounter, | 8702 object_template->SetAccessCheckCallbacks(AccessCounter, NULL); |
| 8790 IndexedAccessCounter); | |
| 8791 Local<v8::Object> object = object_template->NewInstance(); | 8703 Local<v8::Object> object = object_template->NewInstance(); |
| 8792 | 8704 |
| 8793 v8::HandleScope scope1(isolate); | 8705 v8::HandleScope scope1(isolate); |
| 8794 | 8706 |
| 8795 // Create another environment. | 8707 // Create another environment. |
| 8796 v8::Local<Context> context1 = Context::New(isolate); | 8708 v8::Local<Context> context1 = Context::New(isolate); |
| 8797 context1->Enter(); | 8709 context1->Enter(); |
| 8798 | 8710 |
| 8799 // Make easy access to the object from the other environment. | 8711 // Make easy access to the object from the other environment. |
| 8800 v8::Handle<v8::Object> global1 = context1->Global(); | 8712 v8::Handle<v8::Object> global1 = context1->Global(); |
| 8801 global1->Set(v8_str("obj"), object); | 8713 global1->Set(v8_str("obj"), object); |
| 8802 | 8714 |
| 8803 v8::Handle<Value> value; | 8715 v8::Handle<Value> value; |
| 8804 | 8716 |
| 8805 // Check that the named access-control function is called every time. | 8717 // Check that the named access-control function is called every time. |
| 8806 CompileRun("function testProp(obj) {" | 8718 CompileRun("function testProp(obj) {" |
| 8807 " for (var i = 0; i < 10; i++) obj.prop = 1;" | 8719 " for (var i = 0; i < 10; i++) obj.prop = 1;" |
| 8808 " for (var j = 0; j < 10; j++) obj.prop;" | 8720 " for (var j = 0; j < 10; j++) obj.prop;" |
| 8809 " return obj.prop" | 8721 " return obj.prop" |
| 8810 "}"); | 8722 "}"); |
| 8811 value = CompileRun("testProp(obj)"); | 8723 value = CompileRun("testProp(obj)"); |
| 8812 CHECK(value->IsNumber()); | 8724 CHECK(value->IsNumber()); |
| 8813 CHECK_EQ(1, value->Int32Value()); | 8725 CHECK_EQ(1, value->Int32Value()); |
| 8814 CHECK_EQ(21, named_access_count); | 8726 CHECK_EQ(21, access_count); |
| 8815 | 8727 |
| 8816 // Check that the named access-control function is called every time. | 8728 // Check that the named access-control function is called every time. |
| 8817 CompileRun("var p = 'prop';" | 8729 CompileRun("var p = 'prop';" |
| 8818 "function testKeyed(obj) {" | 8730 "function testKeyed(obj) {" |
| 8819 " for (var i = 0; i < 10; i++) obj[p] = 1;" | 8731 " for (var i = 0; i < 10; i++) obj[p] = 1;" |
| 8820 " for (var j = 0; j < 10; j++) obj[p];" | 8732 " for (var j = 0; j < 10; j++) obj[p];" |
| 8821 " return obj[p];" | 8733 " return obj[p];" |
| 8822 "}"); | 8734 "}"); |
| 8823 // Use obj which requires access checks. No inline caching is used | 8735 // Use obj which requires access checks. No inline caching is used |
| 8824 // in that case. | 8736 // in that case. |
| 8825 value = CompileRun("testKeyed(obj)"); | 8737 value = CompileRun("testKeyed(obj)"); |
| 8826 CHECK(value->IsNumber()); | 8738 CHECK(value->IsNumber()); |
| 8827 CHECK_EQ(1, value->Int32Value()); | 8739 CHECK_EQ(1, value->Int32Value()); |
| 8828 CHECK_EQ(42, named_access_count); | 8740 CHECK_EQ(42, access_count); |
| 8829 // Force the inline caches into generic state and try again. | 8741 // Force the inline caches into generic state and try again. |
| 8830 CompileRun("testKeyed({ a: 0 })"); | 8742 CompileRun("testKeyed({ a: 0 })"); |
| 8831 CompileRun("testKeyed({ b: 0 })"); | 8743 CompileRun("testKeyed({ b: 0 })"); |
| 8832 value = CompileRun("testKeyed(obj)"); | 8744 value = CompileRun("testKeyed(obj)"); |
| 8833 CHECK(value->IsNumber()); | 8745 CHECK(value->IsNumber()); |
| 8834 CHECK_EQ(1, value->Int32Value()); | 8746 CHECK_EQ(1, value->Int32Value()); |
| 8835 CHECK_EQ(63, named_access_count); | 8747 CHECK_EQ(63, access_count); |
| 8836 | 8748 |
| 8837 // Check that the indexed access-control function is called every time. | 8749 // Check that the indexed access-control function is called every time. |
| 8750 access_count = 0; |
| 8751 |
| 8838 CompileRun("function testIndexed(obj) {" | 8752 CompileRun("function testIndexed(obj) {" |
| 8839 " for (var i = 0; i < 10; i++) obj[0] = 1;" | 8753 " for (var i = 0; i < 10; i++) obj[0] = 1;" |
| 8840 " for (var j = 0; j < 10; j++) obj[0];" | 8754 " for (var j = 0; j < 10; j++) obj[0];" |
| 8841 " return obj[0]" | 8755 " return obj[0]" |
| 8842 "}"); | 8756 "}"); |
| 8843 value = CompileRun("testIndexed(obj)"); | 8757 value = CompileRun("testIndexed(obj)"); |
| 8844 CHECK(value->IsNumber()); | 8758 CHECK(value->IsNumber()); |
| 8845 CHECK_EQ(1, value->Int32Value()); | 8759 CHECK_EQ(1, value->Int32Value()); |
| 8846 CHECK_EQ(21, indexed_access_count); | 8760 CHECK_EQ(21, access_count); |
| 8847 // Force the inline caches into generic state. | 8761 // Force the inline caches into generic state. |
| 8848 CompileRun("testIndexed(new Array(1))"); | 8762 CompileRun("testIndexed(new Array(1))"); |
| 8849 // Test that the indexed access check is called. | 8763 // Test that the indexed access check is called. |
| 8850 value = CompileRun("testIndexed(obj)"); | 8764 value = CompileRun("testIndexed(obj)"); |
| 8851 CHECK(value->IsNumber()); | 8765 CHECK(value->IsNumber()); |
| 8852 CHECK_EQ(1, value->Int32Value()); | 8766 CHECK_EQ(1, value->Int32Value()); |
| 8853 CHECK_EQ(42, indexed_access_count); | 8767 CHECK_EQ(42, access_count); |
| 8854 | 8768 |
| 8769 access_count = 0; |
| 8855 // Check that the named access check is called when invoking | 8770 // Check that the named access check is called when invoking |
| 8856 // functions on an object that requires access checks. | 8771 // functions on an object that requires access checks. |
| 8857 CompileRun("obj.f = function() {}"); | 8772 CompileRun("obj.f = function() {}"); |
| 8858 CompileRun("function testCallNormal(obj) {" | 8773 CompileRun("function testCallNormal(obj) {" |
| 8859 " for (var i = 0; i < 10; i++) obj.f();" | 8774 " for (var i = 0; i < 10; i++) obj.f();" |
| 8860 "}"); | 8775 "}"); |
| 8861 CompileRun("testCallNormal(obj)"); | 8776 CompileRun("testCallNormal(obj)"); |
| 8862 CHECK_EQ(74, named_access_count); | 8777 printf("%i\n", access_count); |
| 8778 CHECK_EQ(11, access_count); |
| 8863 | 8779 |
| 8864 // Force obj into slow case. | 8780 // Force obj into slow case. |
| 8865 value = CompileRun("delete obj.prop"); | 8781 value = CompileRun("delete obj.prop"); |
| 8866 CHECK(value->BooleanValue()); | 8782 CHECK(value->BooleanValue()); |
| 8867 // Force inline caches into dictionary probing mode. | 8783 // Force inline caches into dictionary probing mode. |
| 8868 CompileRun("var o = { x: 0 }; delete o.x; testProp(o);"); | 8784 CompileRun("var o = { x: 0 }; delete o.x; testProp(o);"); |
| 8869 // Test that the named access check is called. | 8785 // Test that the named access check is called. |
| 8870 value = CompileRun("testProp(obj);"); | 8786 value = CompileRun("testProp(obj);"); |
| 8871 CHECK(value->IsNumber()); | 8787 CHECK(value->IsNumber()); |
| 8872 CHECK_EQ(1, value->Int32Value()); | 8788 CHECK_EQ(1, value->Int32Value()); |
| 8873 CHECK_EQ(96, named_access_count); | 8789 CHECK_EQ(33, access_count); |
| 8874 | 8790 |
| 8875 // Force the call inline cache into dictionary probing mode. | 8791 // Force the call inline cache into dictionary probing mode. |
| 8876 CompileRun("o.f = function() {}; testCallNormal(o)"); | 8792 CompileRun("o.f = function() {}; testCallNormal(o)"); |
| 8877 // Test that the named access check is still called for each | 8793 // Test that the named access check is still called for each |
| 8878 // invocation of the function. | 8794 // invocation of the function. |
| 8879 value = CompileRun("testCallNormal(obj)"); | 8795 value = CompileRun("testCallNormal(obj)"); |
| 8880 CHECK_EQ(106, named_access_count); | 8796 CHECK_EQ(43, access_count); |
| 8881 | 8797 |
| 8882 context1->Exit(); | 8798 context1->Exit(); |
| 8883 context0->Exit(); | 8799 context0->Exit(); |
| 8884 } | |
| 8885 | |
| 8886 | |
| 8887 static bool NamedAccessFlatten(Local<v8::Object> global, | |
| 8888 Local<Value> name, | |
| 8889 v8::AccessType type, | |
| 8890 Local<Value> data) { | |
| 8891 char buf[100]; | |
| 8892 int len; | |
| 8893 | |
| 8894 CHECK(name->IsString()); | |
| 8895 | |
| 8896 memset(buf, 0x1, sizeof(buf)); | |
| 8897 len = name.As<String>()->WriteOneByte(reinterpret_cast<uint8_t*>(buf)); | |
| 8898 CHECK_EQ(4, len); | |
| 8899 | |
| 8900 uint16_t buf2[100]; | |
| 8901 | |
| 8902 memset(buf, 0x1, sizeof(buf)); | |
| 8903 len = name.As<String>()->Write(buf2); | |
| 8904 CHECK_EQ(4, len); | |
| 8905 | |
| 8906 return true; | |
| 8907 } | |
| 8908 | |
| 8909 | |
| 8910 static bool IndexedAccessFlatten(Local<v8::Object> global, | |
| 8911 uint32_t key, | |
| 8912 v8::AccessType type, | |
| 8913 Local<Value> data) { | |
| 8914 return true; | |
| 8915 } | |
| 8916 | |
| 8917 | |
| 8918 // Regression test. In access checks, operations that may cause | |
| 8919 // garbage collection are not allowed. It used to be the case that | |
| 8920 // using the Write operation on a string could cause a garbage | |
| 8921 // collection due to flattening of the string. This is no longer the | |
| 8922 // case. | |
| 8923 THREADED_TEST(AccessControlFlatten) { | |
| 8924 named_access_count = 0; | |
| 8925 indexed_access_count = 0; | |
| 8926 | |
| 8927 v8::Isolate* isolate = CcTest::isolate(); | |
| 8928 v8::HandleScope handle_scope(isolate); | |
| 8929 | |
| 8930 // Create an environment. | |
| 8931 v8::Local<Context> context0 = Context::New(isolate); | |
| 8932 context0->Enter(); | |
| 8933 | |
| 8934 // Create an object that requires access-check functions to be | |
| 8935 // called for cross-domain access. | |
| 8936 v8::Handle<v8::ObjectTemplate> object_template = | |
| 8937 v8::ObjectTemplate::New(isolate); | |
| 8938 object_template->SetAccessCheckCallbacks(NamedAccessFlatten, | |
| 8939 IndexedAccessFlatten); | |
| 8940 Local<v8::Object> object = object_template->NewInstance(); | |
| 8941 | |
| 8942 v8::HandleScope scope1(isolate); | |
| 8943 | |
| 8944 // Create another environment. | |
| 8945 v8::Local<Context> context1 = Context::New(isolate); | |
| 8946 context1->Enter(); | |
| 8947 | |
| 8948 // Make easy access to the object from the other environment. | |
| 8949 v8::Handle<v8::Object> global1 = context1->Global(); | |
| 8950 global1->Set(v8_str("obj"), object); | |
| 8951 | |
| 8952 v8::Handle<Value> value; | |
| 8953 | |
| 8954 value = v8_compile("var p = 'as' + 'df';")->Run(); | |
| 8955 value = v8_compile("obj[p];")->Run(); | |
| 8956 | |
| 8957 context1->Exit(); | |
| 8958 context0->Exit(); | |
| 8959 } | 8800 } |
| 8960 | 8801 |
| 8961 | 8802 |
| 8962 THREADED_TEST(Version) { v8::V8::GetVersion(); } | 8803 THREADED_TEST(Version) { v8::V8::GetVersion(); } |
| 8963 | 8804 |
| 8964 | 8805 |
| 8965 static void InstanceFunctionCallback( | 8806 static void InstanceFunctionCallback( |
| 8966 const v8::FunctionCallbackInfo<v8::Value>& args) { | 8807 const v8::FunctionCallbackInfo<v8::Value>& args) { |
| 8967 ApiTestFuzzer::Fuzz(); | 8808 ApiTestFuzzer::Fuzz(); |
| 8968 args.GetReturnValue().Set(v8_num(12)); | 8809 args.GetReturnValue().Set(v8_num(12)); |
| (...skipping 3700 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12669 elms->Get(v8::Integer::New(isolate, 0)), elmc0, elmv0); | 12510 elms->Get(v8::Integer::New(isolate, 0)), elmc0, elmv0); |
| 12670 | 12511 |
| 12671 v8::Handle<v8::Value> val = elms->Get(v8::Integer::New(isolate, 0)); | 12512 v8::Handle<v8::Value> val = elms->Get(v8::Integer::New(isolate, 0)); |
| 12672 v8::Handle<v8::Array> props = val.As<v8::Object>()->GetPropertyNames(); | 12513 v8::Handle<v8::Array> props = val.As<v8::Object>()->GetPropertyNames(); |
| 12673 CHECK_EQ(0u, props->Length()); | 12514 CHECK_EQ(0u, props->Length()); |
| 12674 for (uint32_t i = 0; i < props->Length(); i++) { | 12515 for (uint32_t i = 0; i < props->Length(); i++) { |
| 12675 printf("p[%u]\n", i); | 12516 printf("p[%u]\n", i); |
| 12676 } | 12517 } |
| 12677 } | 12518 } |
| 12678 | 12519 |
| 12679 static bool NamedSetAccessBlocker(Local<v8::Object> obj, | |
| 12680 Local<Value> name, | |
| 12681 v8::AccessType type, | |
| 12682 Local<Value> data) { | |
| 12683 return type != v8::ACCESS_SET; | |
| 12684 } | |
| 12685 | |
| 12686 | |
| 12687 static bool IndexedSetAccessBlocker(Local<v8::Object> obj, | |
| 12688 uint32_t key, | |
| 12689 v8::AccessType type, | |
| 12690 Local<Value> data) { | |
| 12691 return type != v8::ACCESS_SET; | |
| 12692 } | |
| 12693 | |
| 12694 | |
| 12695 THREADED_TEST(DisableAccessChecksWhileConfiguring) { | |
| 12696 LocalContext context; | |
| 12697 v8::Isolate* isolate = context->GetIsolate(); | |
| 12698 v8::HandleScope scope(isolate); | |
| 12699 Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); | |
| 12700 templ->SetAccessCheckCallbacks(NamedSetAccessBlocker, | |
| 12701 IndexedSetAccessBlocker); | |
| 12702 templ->Set(v8_str("x"), v8::True(isolate)); | |
| 12703 Local<v8::Object> instance = templ->NewInstance(); | |
| 12704 context->Global()->Set(v8_str("obj"), instance); | |
| 12705 Local<Value> value = CompileRun("obj.x"); | |
| 12706 CHECK(value->BooleanValue()); | |
| 12707 } | |
| 12708 | |
| 12709 | |
| 12710 static bool NamedGetAccessBlocker(Local<v8::Object> obj, | |
| 12711 Local<Value> name, | |
| 12712 v8::AccessType type, | |
| 12713 Local<Value> data) { | |
| 12714 return false; | |
| 12715 } | |
| 12716 | |
| 12717 | |
| 12718 static bool IndexedGetAccessBlocker(Local<v8::Object> obj, | |
| 12719 uint32_t key, | |
| 12720 v8::AccessType type, | |
| 12721 Local<Value> data) { | |
| 12722 return false; | |
| 12723 } | |
| 12724 | |
| 12725 | |
| 12726 | 12520 |
| 12727 THREADED_TEST(AccessChecksReenabledCorrectly) { | 12521 THREADED_TEST(AccessChecksReenabledCorrectly) { |
| 12728 LocalContext context; | 12522 LocalContext context; |
| 12729 v8::Isolate* isolate = context->GetIsolate(); | 12523 v8::Isolate* isolate = context->GetIsolate(); |
| 12730 v8::HandleScope scope(isolate); | 12524 v8::HandleScope scope(isolate); |
| 12731 Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); | 12525 Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); |
| 12732 templ->SetAccessCheckCallbacks(NamedGetAccessBlocker, | 12526 templ->SetAccessCheckCallbacks(AccessAlwaysBlocked, NULL); |
| 12733 IndexedGetAccessBlocker); | |
| 12734 templ->Set(v8_str("a"), v8_str("a")); | 12527 templ->Set(v8_str("a"), v8_str("a")); |
| 12735 // Add more than 8 (see kMaxFastProperties) properties | 12528 // Add more than 8 (see kMaxFastProperties) properties |
| 12736 // so that the constructor will force copying map. | 12529 // so that the constructor will force copying map. |
| 12737 // Cannot sprintf, gcc complains unsafety. | 12530 // Cannot sprintf, gcc complains unsafety. |
| 12738 char buf[4]; | 12531 char buf[4]; |
| 12739 for (char i = '0'; i <= '9' ; i++) { | 12532 for (char i = '0'; i <= '9' ; i++) { |
| 12740 buf[0] = i; | 12533 buf[0] = i; |
| 12741 for (char j = '0'; j <= '9'; j++) { | 12534 for (char j = '0'; j <= '9'; j++) { |
| 12742 buf[1] = j; | 12535 buf[1] = j; |
| 12743 for (char k = '0'; k <= '9'; k++) { | 12536 for (char k = '0'; k <= '9'; k++) { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 12755 CHECK(value_1.IsEmpty()); | 12548 CHECK(value_1.IsEmpty()); |
| 12756 | 12549 |
| 12757 Local<v8::Object> instance_2 = templ->NewInstance(); | 12550 Local<v8::Object> instance_2 = templ->NewInstance(); |
| 12758 context->Global()->Set(v8_str("obj_2"), instance_2); | 12551 context->Global()->Set(v8_str("obj_2"), instance_2); |
| 12759 | 12552 |
| 12760 Local<Value> value_2 = CompileRun("obj_2.a"); | 12553 Local<Value> value_2 = CompileRun("obj_2.a"); |
| 12761 CHECK(value_2.IsEmpty()); | 12554 CHECK(value_2.IsEmpty()); |
| 12762 } | 12555 } |
| 12763 | 12556 |
| 12764 | 12557 |
| 12765 // This tests that access check information remains on the global | |
| 12766 // object template when creating contexts. | |
| 12767 THREADED_TEST(AccessControlRepeatedContextCreation) { | |
| 12768 v8::Isolate* isolate = CcTest::isolate(); | |
| 12769 v8::HandleScope handle_scope(isolate); | |
| 12770 v8::Handle<v8::ObjectTemplate> global_template = | |
| 12771 v8::ObjectTemplate::New(isolate); | |
| 12772 global_template->SetAccessCheckCallbacks(NamedSetAccessBlocker, | |
| 12773 IndexedSetAccessBlocker); | |
| 12774 i::Handle<i::ObjectTemplateInfo> internal_template = | |
| 12775 v8::Utils::OpenHandle(*global_template); | |
| 12776 CHECK(!internal_template->constructor()->IsUndefined()); | |
| 12777 i::Handle<i::FunctionTemplateInfo> constructor( | |
| 12778 i::FunctionTemplateInfo::cast(internal_template->constructor())); | |
| 12779 CHECK(!constructor->access_check_info()->IsUndefined()); | |
| 12780 v8::Local<Context> context0(Context::New(isolate, NULL, global_template)); | |
| 12781 CHECK(!context0.IsEmpty()); | |
| 12782 CHECK(!constructor->access_check_info()->IsUndefined()); | |
| 12783 } | |
| 12784 | |
| 12785 | |
| 12786 THREADED_TEST(TurnOnAccessCheck) { | 12558 THREADED_TEST(TurnOnAccessCheck) { |
| 12787 v8::Isolate* isolate = CcTest::isolate(); | 12559 v8::Isolate* isolate = CcTest::isolate(); |
| 12788 v8::HandleScope handle_scope(isolate); | 12560 v8::HandleScope handle_scope(isolate); |
| 12789 | 12561 |
| 12790 // Create an environment with access check to the global object disabled by | 12562 // Create an environment with access check to the global object disabled by |
| 12791 // default. | 12563 // default. |
| 12792 v8::Handle<v8::ObjectTemplate> global_template = | 12564 v8::Handle<v8::ObjectTemplate> global_template = |
| 12793 v8::ObjectTemplate::New(isolate); | 12565 v8::ObjectTemplate::New(isolate); |
| 12794 global_template->SetAccessCheckCallbacks(NamedGetAccessBlocker, | 12566 global_template->SetAccessCheckCallbacks(AccessAlwaysBlocked, NULL, |
| 12795 IndexedGetAccessBlocker, | 12567 v8::Handle<v8::Value>(), false); |
| 12796 v8::Handle<v8::Value>(), | |
| 12797 false); | |
| 12798 v8::Local<Context> context = Context::New(isolate, NULL, global_template); | 12568 v8::Local<Context> context = Context::New(isolate, NULL, global_template); |
| 12799 Context::Scope context_scope(context); | 12569 Context::Scope context_scope(context); |
| 12800 | 12570 |
| 12801 // Set up a property and a number of functions. | 12571 // Set up a property and a number of functions. |
| 12802 context->Global()->Set(v8_str("a"), v8_num(1)); | 12572 context->Global()->Set(v8_str("a"), v8_num(1)); |
| 12803 CompileRun("function f1() {return a;}" | 12573 CompileRun("function f1() {return a;}" |
| 12804 "function f2() {return a;}" | 12574 "function f2() {return a;}" |
| 12805 "function g1() {return h();}" | 12575 "function g1() {return h();}" |
| 12806 "function g2() {return h();}" | 12576 "function g2() {return h();}" |
| 12807 "function h() {return 1;}"); | 12577 "function h() {return 1;}"); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12843 CHECK(f1->Call(global, 0, NULL).IsEmpty()); | 12613 CHECK(f1->Call(global, 0, NULL).IsEmpty()); |
| 12844 CHECK(f2->Call(global, 0, NULL).IsEmpty()); | 12614 CHECK(f2->Call(global, 0, NULL).IsEmpty()); |
| 12845 CHECK(g1->Call(global, 0, NULL).IsEmpty()); | 12615 CHECK(g1->Call(global, 0, NULL).IsEmpty()); |
| 12846 CHECK(g2->Call(global, 0, NULL).IsEmpty()); | 12616 CHECK(g2->Call(global, 0, NULL).IsEmpty()); |
| 12847 | 12617 |
| 12848 // No failing access check when just returning a constant. | 12618 // No failing access check when just returning a constant. |
| 12849 CHECK(h->Call(global, 0, NULL)->Equals(v8_num(1))); | 12619 CHECK(h->Call(global, 0, NULL)->Equals(v8_num(1))); |
| 12850 } | 12620 } |
| 12851 | 12621 |
| 12852 | 12622 |
| 12853 static const char* kPropertyA = "a"; | |
| 12854 static const char* kPropertyH = "h"; | |
| 12855 | |
| 12856 static bool NamedGetAccessBlockAandH(Local<v8::Object> obj, | |
| 12857 Local<Value> name, | |
| 12858 v8::AccessType type, | |
| 12859 Local<Value> data) { | |
| 12860 if (!name->IsString()) return false; | |
| 12861 i::Handle<i::String> name_handle = | |
| 12862 v8::Utils::OpenHandle(String::Cast(*name)); | |
| 12863 return !name_handle->IsUtf8EqualTo(i::CStrVector(kPropertyA)) | |
| 12864 && !name_handle->IsUtf8EqualTo(i::CStrVector(kPropertyH)); | |
| 12865 } | |
| 12866 | |
| 12867 | |
| 12868 THREADED_TEST(TurnOnAccessCheckAndRecompile) { | |
| 12869 v8::Isolate* isolate = CcTest::isolate(); | |
| 12870 v8::HandleScope handle_scope(isolate); | |
| 12871 | |
| 12872 // Create an environment with access check to the global object disabled by | |
| 12873 // default. When the registered access checker will block access to properties | |
| 12874 // a and h. | |
| 12875 v8::Handle<v8::ObjectTemplate> global_template = | |
| 12876 v8::ObjectTemplate::New(isolate); | |
| 12877 global_template->SetAccessCheckCallbacks(NamedGetAccessBlockAandH, | |
| 12878 IndexedGetAccessBlocker, | |
| 12879 v8::Handle<v8::Value>(), | |
| 12880 false); | |
| 12881 v8::Local<Context> context = Context::New(isolate, NULL, global_template); | |
| 12882 Context::Scope context_scope(context); | |
| 12883 | |
| 12884 // Set up a property and a number of functions. | |
| 12885 context->Global()->Set(v8_str("a"), v8_num(1)); | |
| 12886 static const char* source = "function f1() {return a;}" | |
| 12887 "function f2() {return a;}" | |
| 12888 "function g1() {return h();}" | |
| 12889 "function g2() {return h();}" | |
| 12890 "function h() {return 1;}"; | |
| 12891 | |
| 12892 CompileRun(source); | |
| 12893 Local<Function> f1; | |
| 12894 Local<Function> f2; | |
| 12895 Local<Function> g1; | |
| 12896 Local<Function> g2; | |
| 12897 Local<Function> h; | |
| 12898 f1 = Local<Function>::Cast(context->Global()->Get(v8_str("f1"))); | |
| 12899 f2 = Local<Function>::Cast(context->Global()->Get(v8_str("f2"))); | |
| 12900 g1 = Local<Function>::Cast(context->Global()->Get(v8_str("g1"))); | |
| 12901 g2 = Local<Function>::Cast(context->Global()->Get(v8_str("g2"))); | |
| 12902 h = Local<Function>::Cast(context->Global()->Get(v8_str("h"))); | |
| 12903 | |
| 12904 // Get the global object. | |
| 12905 v8::Handle<v8::Object> global = context->Global(); | |
| 12906 | |
| 12907 // Call f1 one time and f2 a number of times. This will ensure that f1 still | |
| 12908 // uses the runtime system to retreive property a whereas f2 uses global load | |
| 12909 // inline cache. | |
| 12910 CHECK(f1->Call(global, 0, NULL)->Equals(v8_num(1))); | |
| 12911 for (int i = 0; i < 4; i++) { | |
| 12912 CHECK(f2->Call(global, 0, NULL)->Equals(v8_num(1))); | |
| 12913 } | |
| 12914 | |
| 12915 // Same for g1 and g2. | |
| 12916 CHECK(g1->Call(global, 0, NULL)->Equals(v8_num(1))); | |
| 12917 for (int i = 0; i < 4; i++) { | |
| 12918 CHECK(g2->Call(global, 0, NULL)->Equals(v8_num(1))); | |
| 12919 } | |
| 12920 | |
| 12921 // Detach the global and turn on access check now blocking access to property | |
| 12922 // a and function h. | |
| 12923 Local<Object> hidden_global = Local<Object>::Cast( | |
| 12924 context->Global()->GetPrototype()); | |
| 12925 context->DetachGlobal(); | |
| 12926 hidden_global->TurnOnAccessCheck(); | |
| 12927 | |
| 12928 // Failing access check results in exception. | |
| 12929 CHECK(f1->Call(global, 0, NULL).IsEmpty()); | |
| 12930 CHECK(f2->Call(global, 0, NULL).IsEmpty()); | |
| 12931 CHECK(g1->Call(global, 0, NULL).IsEmpty()); | |
| 12932 CHECK(g2->Call(global, 0, NULL).IsEmpty()); | |
| 12933 | |
| 12934 // No failing access check when just returning a constant. | |
| 12935 CHECK(h->Call(global, 0, NULL)->Equals(v8_num(1))); | |
| 12936 | |
| 12937 // Now compile the source again. And get the newly compiled functions, except | |
| 12938 // for h for which access is blocked. | |
| 12939 CompileRun(source); | |
| 12940 f1 = Local<Function>::Cast(hidden_global->Get(v8_str("f1"))); | |
| 12941 f2 = Local<Function>::Cast(hidden_global->Get(v8_str("f2"))); | |
| 12942 g1 = Local<Function>::Cast(hidden_global->Get(v8_str("g1"))); | |
| 12943 g2 = Local<Function>::Cast(hidden_global->Get(v8_str("g2"))); | |
| 12944 CHECK(hidden_global->Get(v8_str("h")).IsEmpty()); | |
| 12945 | |
| 12946 // Failing access check results in exception. | |
| 12947 v8::Local<v8::Value> result = f1->Call(global, 0, NULL); | |
| 12948 CHECK(result.IsEmpty()); | |
| 12949 CHECK(f1->Call(global, 0, NULL).IsEmpty()); | |
| 12950 CHECK(f2->Call(global, 0, NULL).IsEmpty()); | |
| 12951 CHECK(g1->Call(global, 0, NULL).IsEmpty()); | |
| 12952 CHECK(g2->Call(global, 0, NULL).IsEmpty()); | |
| 12953 } | |
| 12954 | |
| 12955 | |
| 12956 // Tests that ScriptData can be serialized and deserialized. | 12623 // Tests that ScriptData can be serialized and deserialized. |
| 12957 TEST(PreCompileSerialization) { | 12624 TEST(PreCompileSerialization) { |
| 12958 v8::V8::Initialize(); | 12625 v8::V8::Initialize(); |
| 12959 LocalContext env; | 12626 LocalContext env; |
| 12960 v8::Isolate* isolate = env->GetIsolate(); | 12627 v8::Isolate* isolate = env->GetIsolate(); |
| 12961 HandleScope handle_scope(isolate); | 12628 HandleScope handle_scope(isolate); |
| 12962 | 12629 |
| 12963 i::FLAG_min_preparse_length = 0; | 12630 i::FLAG_min_preparse_length = 0; |
| 12964 const char* script = "function foo(a) { return a+1; }"; | 12631 const char* script = "function foo(a) { return a+1; }"; |
| 12965 v8::ScriptCompiler::Source source(v8_str(script)); | 12632 v8::ScriptCompiler::Source source(v8_str(script)); |
| (...skipping 4484 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 17450 v8::V8::Initialize(); | 17117 v8::V8::Initialize(); |
| 17451 v8::V8::SetFailedAccessCheckCallbackFunction(&FailedAccessCheckCallbackGC); | 17118 v8::V8::SetFailedAccessCheckCallbackFunction(&FailedAccessCheckCallbackGC); |
| 17452 | 17119 |
| 17453 v8::Isolate* isolate = CcTest::isolate(); | 17120 v8::Isolate* isolate = CcTest::isolate(); |
| 17454 v8::HandleScope scope(isolate); | 17121 v8::HandleScope scope(isolate); |
| 17455 | 17122 |
| 17456 // Create an ObjectTemplate for global objects and install access | 17123 // Create an ObjectTemplate for global objects and install access |
| 17457 // check callbacks that will block access. | 17124 // check callbacks that will block access. |
| 17458 v8::Handle<v8::ObjectTemplate> global_template = | 17125 v8::Handle<v8::ObjectTemplate> global_template = |
| 17459 v8::ObjectTemplate::New(isolate); | 17126 v8::ObjectTemplate::New(isolate); |
| 17460 global_template->SetAccessCheckCallbacks(NamedGetAccessBlocker, | 17127 global_template->SetAccessCheckCallbacks(AccessAlwaysBlocked, NULL, |
| 17461 IndexedGetAccessBlocker, | 17128 v8::Handle<v8::Value>(), false); |
| 17462 v8::Handle<v8::Value>(), | |
| 17463 false); | |
| 17464 | 17129 |
| 17465 // Create a context and set an x property on it's global object. | 17130 // Create a context and set an x property on it's global object. |
| 17466 LocalContext context0(NULL, global_template); | 17131 LocalContext context0(NULL, global_template); |
| 17467 context0->Global()->Set(v8_str("x"), v8_num(42)); | 17132 context0->Global()->Set(v8_str("x"), v8_num(42)); |
| 17468 v8::Handle<v8::Object> global0 = context0->Global(); | 17133 v8::Handle<v8::Object> global0 = context0->Global(); |
| 17469 | 17134 |
| 17470 // Create a context with a different security token so that the | 17135 // Create a context with a different security token so that the |
| 17471 // failed access check callback will be called on each access. | 17136 // failed access check callback will be called on each access. |
| 17472 LocalContext context1(NULL, global_template); | 17137 LocalContext context1(NULL, global_template); |
| 17473 context1->Global()->Set(v8_str("other"), global0); | 17138 context1->Global()->Set(v8_str("other"), global0); |
| (...skipping 1115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 18589 | 18254 |
| 18590 int elements = CountLiveMapsInMapCache(CcTest::i_isolate()->context()); | 18255 int elements = CountLiveMapsInMapCache(CcTest::i_isolate()->context()); |
| 18591 CHECK_LE(1, elements); | 18256 CHECK_LE(1, elements); |
| 18592 | 18257 |
| 18593 CcTest::heap()->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); | 18258 CcTest::heap()->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); |
| 18594 | 18259 |
| 18595 CHECK_GT(elements, CountLiveMapsInMapCache(CcTest::i_isolate()->context())); | 18260 CHECK_GT(elements, CountLiveMapsInMapCache(CcTest::i_isolate()->context())); |
| 18596 } | 18261 } |
| 18597 | 18262 |
| 18598 | 18263 |
| 18599 static bool BlockProtoNamedSecurityTestCallback(Local<v8::Object> global, | |
| 18600 Local<Value> name, | |
| 18601 v8::AccessType type, | |
| 18602 Local<Value> data) { | |
| 18603 // Only block read access to __proto__. | |
| 18604 if (type == v8::ACCESS_GET && name->IsString() && | |
| 18605 name.As<v8::String>()->Length() == 9 && | |
| 18606 name.As<v8::String>()->Utf8Length() == 9) { | |
| 18607 char buffer[10]; | |
| 18608 CHECK_EQ(10, name.As<v8::String>()->WriteUtf8(buffer)); | |
| 18609 return strncmp(buffer, "__proto__", 9) != 0; | |
| 18610 } | |
| 18611 | |
| 18612 return true; | |
| 18613 } | |
| 18614 | |
| 18615 | |
| 18616 THREADED_TEST(Regress93759) { | 18264 THREADED_TEST(Regress93759) { |
| 18617 v8::Isolate* isolate = CcTest::isolate(); | 18265 v8::Isolate* isolate = CcTest::isolate(); |
| 18618 HandleScope scope(isolate); | 18266 HandleScope scope(isolate); |
| 18619 | 18267 |
| 18620 // Template for object with security check. | 18268 // Template for object with security check. |
| 18621 Local<ObjectTemplate> no_proto_template = v8::ObjectTemplate::New(isolate); | 18269 Local<ObjectTemplate> no_proto_template = v8::ObjectTemplate::New(isolate); |
| 18622 // We don't do indexing, so any callback can be used for that. | 18270 no_proto_template->SetAccessCheckCallbacks(AccessAlwaysBlocked, NULL); |
| 18623 no_proto_template->SetAccessCheckCallbacks( | |
| 18624 BlockProtoNamedSecurityTestCallback, | |
| 18625 IndexedSecurityTestCallback); | |
| 18626 | 18271 |
| 18627 // Templates for objects with hidden prototypes and possibly security check. | 18272 // Templates for objects with hidden prototypes and possibly security check. |
| 18628 Local<FunctionTemplate> hidden_proto_template = | 18273 Local<FunctionTemplate> hidden_proto_template = |
| 18629 v8::FunctionTemplate::New(isolate); | 18274 v8::FunctionTemplate::New(isolate); |
| 18630 hidden_proto_template->SetHiddenPrototype(true); | 18275 hidden_proto_template->SetHiddenPrototype(true); |
| 18631 | 18276 |
| 18632 Local<FunctionTemplate> protected_hidden_proto_template = | 18277 Local<FunctionTemplate> protected_hidden_proto_template = |
| 18633 v8::FunctionTemplate::New(isolate); | 18278 v8::FunctionTemplate::New(isolate); |
| 18634 protected_hidden_proto_template->InstanceTemplate()->SetAccessCheckCallbacks( | 18279 protected_hidden_proto_template->InstanceTemplate()->SetAccessCheckCallbacks( |
| 18635 BlockProtoNamedSecurityTestCallback, | 18280 AccessAlwaysBlocked, NULL); |
| 18636 IndexedSecurityTestCallback); | |
| 18637 protected_hidden_proto_template->SetHiddenPrototype(true); | 18281 protected_hidden_proto_template->SetHiddenPrototype(true); |
| 18638 | 18282 |
| 18639 // Context for "foreign" objects used in test. | 18283 // Context for "foreign" objects used in test. |
| 18640 Local<Context> context = v8::Context::New(isolate); | 18284 Local<Context> context = v8::Context::New(isolate); |
| 18641 context->Enter(); | 18285 context->Enter(); |
| 18642 | 18286 |
| 18643 // Plain object, no security check. | 18287 // Plain object, no security check. |
| 18644 Local<Object> simple_object = Object::New(isolate); | 18288 Local<Object> simple_object = Object::New(isolate); |
| 18645 | 18289 |
| 18646 // Object with explicit security check. | 18290 // Object with explicit security check. |
| 18647 Local<Object> protected_object = | 18291 Local<Object> protected_object = no_proto_template->NewInstance(); |
| 18648 no_proto_template->NewInstance(); | |
| 18649 | 18292 |
| 18650 // JSGlobalProxy object, always have security check. | 18293 // JSGlobalProxy object, always have security check. |
| 18651 Local<Object> proxy_object = | 18294 Local<Object> proxy_object = context->Global(); |
| 18652 context->Global(); | |
| 18653 | 18295 |
| 18654 // Global object, the prototype of proxy_object. No security checks. | 18296 // Global object, the prototype of proxy_object. No security checks. |
| 18655 Local<Object> global_object = proxy_object->GetPrototype()->ToObject(isolate); | 18297 Local<Object> global_object = proxy_object->GetPrototype()->ToObject(isolate); |
| 18656 | 18298 |
| 18657 // Hidden prototype without security check. | 18299 // Hidden prototype without security check. |
| 18658 Local<Object> hidden_prototype = | 18300 Local<Object> hidden_prototype = |
| 18659 hidden_proto_template->GetFunction()->NewInstance(); | 18301 hidden_proto_template->GetFunction()->NewInstance(); |
| 18660 Local<Object> object_with_hidden = | 18302 Local<Object> object_with_hidden = |
| 18661 Object::New(isolate); | 18303 Object::New(isolate); |
| 18662 object_with_hidden->SetPrototype(hidden_prototype); | 18304 object_with_hidden->SetPrototype(hidden_prototype); |
| (...skipping 1145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 19808 | 19450 |
| 19809 | 19451 |
| 19810 THREADED_TEST(SemaphoreInterruption) { | 19452 THREADED_TEST(SemaphoreInterruption) { |
| 19811 ThreadInterruptTest().RunTest(); | 19453 ThreadInterruptTest().RunTest(); |
| 19812 } | 19454 } |
| 19813 | 19455 |
| 19814 | 19456 |
| 19815 #endif // V8_OS_POSIX | 19457 #endif // V8_OS_POSIX |
| 19816 | 19458 |
| 19817 | 19459 |
| 19818 static bool NamedAccessAlwaysBlocked(Local<v8::Object> global, | |
| 19819 Local<Value> name, | |
| 19820 v8::AccessType type, | |
| 19821 Local<Value> data) { | |
| 19822 i::PrintF("Named access blocked.\n"); | |
| 19823 return false; | |
| 19824 } | |
| 19825 | |
| 19826 | |
| 19827 static bool IndexAccessAlwaysBlocked(Local<v8::Object> global, | |
| 19828 uint32_t key, | |
| 19829 v8::AccessType type, | |
| 19830 Local<Value> data) { | |
| 19831 i::PrintF("Indexed access blocked.\n"); | |
| 19832 return false; | |
| 19833 } | |
| 19834 | |
| 19835 | |
| 19836 void UnreachableCallback(const v8::FunctionCallbackInfo<v8::Value>& args) { | 19460 void UnreachableCallback(const v8::FunctionCallbackInfo<v8::Value>& args) { |
| 19837 CHECK(false); | 19461 CHECK(false); |
| 19838 } | 19462 } |
| 19839 | 19463 |
| 19840 | 19464 |
| 19841 TEST(JSONStringifyAccessCheck) { | 19465 TEST(JSONStringifyAccessCheck) { |
| 19842 v8::V8::Initialize(); | 19466 v8::V8::Initialize(); |
| 19843 v8::Isolate* isolate = CcTest::isolate(); | 19467 v8::Isolate* isolate = CcTest::isolate(); |
| 19844 v8::HandleScope scope(isolate); | 19468 v8::HandleScope scope(isolate); |
| 19845 | 19469 |
| 19846 // Create an ObjectTemplate for global objects and install access | 19470 // Create an ObjectTemplate for global objects and install access |
| 19847 // check callbacks that will block access. | 19471 // check callbacks that will block access. |
| 19848 v8::Handle<v8::ObjectTemplate> global_template = | 19472 v8::Handle<v8::ObjectTemplate> global_template = |
| 19849 v8::ObjectTemplate::New(isolate); | 19473 v8::ObjectTemplate::New(isolate); |
| 19850 global_template->SetAccessCheckCallbacks(NamedAccessAlwaysBlocked, | 19474 global_template->SetAccessCheckCallbacks(AccessAlwaysBlocked, NULL); |
| 19851 IndexAccessAlwaysBlocked); | |
| 19852 | 19475 |
| 19853 // Create a context and set an x property on it's global object. | 19476 // Create a context and set an x property on it's global object. |
| 19854 LocalContext context0(NULL, global_template); | 19477 LocalContext context0(NULL, global_template); |
| 19855 v8::Handle<v8::Object> global0 = context0->Global(); | 19478 v8::Handle<v8::Object> global0 = context0->Global(); |
| 19856 global0->Set(v8_str("x"), v8_num(42)); | 19479 global0->Set(v8_str("x"), v8_num(42)); |
| 19857 ExpectString("JSON.stringify(this)", "{\"x\":42}"); | 19480 ExpectString("JSON.stringify(this)", "{\"x\":42}"); |
| 19858 | 19481 |
| 19859 for (int i = 0; i < 2; i++) { | 19482 for (int i = 0; i < 2; i++) { |
| 19860 if (i == 1) { | 19483 if (i == 1) { |
| 19861 // Install a toJSON function on the second run. | 19484 // Install a toJSON function on the second run. |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 19939 i::FLAG_allow_natives_syntax = true; | 19562 i::FLAG_allow_natives_syntax = true; |
| 19940 v8::V8::Initialize(); | 19563 v8::V8::Initialize(); |
| 19941 v8::V8::SetFailedAccessCheckCallbackFunction(&FailedAccessCheckThrows); | 19564 v8::V8::SetFailedAccessCheckCallbackFunction(&FailedAccessCheckThrows); |
| 19942 v8::Isolate* isolate = CcTest::isolate(); | 19565 v8::Isolate* isolate = CcTest::isolate(); |
| 19943 v8::HandleScope scope(isolate); | 19566 v8::HandleScope scope(isolate); |
| 19944 | 19567 |
| 19945 // Create an ObjectTemplate for global objects and install access | 19568 // Create an ObjectTemplate for global objects and install access |
| 19946 // check callbacks that will block access. | 19569 // check callbacks that will block access. |
| 19947 v8::Handle<v8::ObjectTemplate> global_template = | 19570 v8::Handle<v8::ObjectTemplate> global_template = |
| 19948 v8::ObjectTemplate::New(isolate); | 19571 v8::ObjectTemplate::New(isolate); |
| 19949 global_template->SetAccessCheckCallbacks(NamedAccessAlwaysBlocked, | 19572 global_template->SetAccessCheckCallbacks(AccessAlwaysBlocked, NULL); |
| 19950 IndexAccessAlwaysBlocked); | |
| 19951 | 19573 |
| 19952 // Create a context and set an x property on it's global object. | 19574 // Create a context and set an x property on it's global object. |
| 19953 LocalContext context0(NULL, global_template); | 19575 LocalContext context0(NULL, global_template); |
| 19954 v8::Handle<v8::Object> global0 = context0->Global(); | 19576 v8::Handle<v8::Object> global0 = context0->Global(); |
| 19955 | 19577 |
| 19956 // Create a context with a different security token so that the | 19578 // Create a context with a different security token so that the |
| 19957 // failed access check callback will be called on each access. | 19579 // failed access check callback will be called on each access. |
| 19958 LocalContext context1(NULL, global_template); | 19580 LocalContext context1(NULL, global_template); |
| 19959 context1->Global()->Set(v8_str("other"), global0); | 19581 context1->Global()->Set(v8_str("other"), global0); |
| 19960 | 19582 |
| (...skipping 1034 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 20995 CHECK(try_catch.HasCaught()); | 20617 CHECK(try_catch.HasCaught()); |
| 20996 } | 20618 } |
| 20997 | 20619 |
| 20998 | 20620 |
| 20999 TEST(Regress354123) { | 20621 TEST(Regress354123) { |
| 21000 LocalContext current; | 20622 LocalContext current; |
| 21001 v8::Isolate* isolate = current->GetIsolate(); | 20623 v8::Isolate* isolate = current->GetIsolate(); |
| 21002 v8::HandleScope scope(isolate); | 20624 v8::HandleScope scope(isolate); |
| 21003 | 20625 |
| 21004 v8::Handle<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(isolate); | 20626 v8::Handle<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(isolate); |
| 21005 templ->SetAccessCheckCallbacks(NamedAccessCounter, IndexedAccessCounter); | 20627 templ->SetAccessCheckCallbacks(AccessCounter, NULL); |
| 21006 current->Global()->Set(v8_str("friend"), templ->NewInstance()); | 20628 current->Global()->Set(v8_str("friend"), templ->NewInstance()); |
| 21007 | 20629 |
| 21008 // Test access using __proto__ from the prototype chain. | 20630 // Test access using __proto__ from the prototype chain. |
| 21009 named_access_count = 0; | 20631 access_count = 0; |
| 21010 CompileRun("friend.__proto__ = {};"); | 20632 CompileRun("friend.__proto__ = {};"); |
| 21011 CHECK_EQ(2, named_access_count); | 20633 CHECK_EQ(2, access_count); |
| 21012 CompileRun("friend.__proto__;"); | 20634 CompileRun("friend.__proto__;"); |
| 21013 CHECK_EQ(4, named_access_count); | 20635 CHECK_EQ(4, access_count); |
| 21014 | 20636 |
| 21015 // Test access using __proto__ as a hijacked function (A). | 20637 // Test access using __proto__ as a hijacked function (A). |
| 21016 named_access_count = 0; | 20638 access_count = 0; |
| 21017 CompileRun("var p = Object.prototype;" | 20639 CompileRun("var p = Object.prototype;" |
| 21018 "var f = Object.getOwnPropertyDescriptor(p, '__proto__').set;" | 20640 "var f = Object.getOwnPropertyDescriptor(p, '__proto__').set;" |
| 21019 "f.call(friend, {});"); | 20641 "f.call(friend, {});"); |
| 21020 CHECK_EQ(1, named_access_count); | 20642 CHECK_EQ(1, access_count); |
| 21021 CompileRun("var p = Object.prototype;" | 20643 CompileRun("var p = Object.prototype;" |
| 21022 "var f = Object.getOwnPropertyDescriptor(p, '__proto__').get;" | 20644 "var f = Object.getOwnPropertyDescriptor(p, '__proto__').get;" |
| 21023 "f.call(friend);"); | 20645 "f.call(friend);"); |
| 21024 CHECK_EQ(2, named_access_count); | 20646 CHECK_EQ(2, access_count); |
| 21025 | 20647 |
| 21026 // Test access using __proto__ as a hijacked function (B). | 20648 // Test access using __proto__ as a hijacked function (B). |
| 21027 named_access_count = 0; | 20649 access_count = 0; |
| 21028 CompileRun("var f = Object.prototype.__lookupSetter__('__proto__');" | 20650 CompileRun("var f = Object.prototype.__lookupSetter__('__proto__');" |
| 21029 "f.call(friend, {});"); | 20651 "f.call(friend, {});"); |
| 21030 CHECK_EQ(1, named_access_count); | 20652 CHECK_EQ(1, access_count); |
| 21031 CompileRun("var f = Object.prototype.__lookupGetter__('__proto__');" | 20653 CompileRun("var f = Object.prototype.__lookupGetter__('__proto__');" |
| 21032 "f.call(friend);"); | 20654 "f.call(friend);"); |
| 21033 CHECK_EQ(2, named_access_count); | 20655 CHECK_EQ(2, access_count); |
| 21034 | 20656 |
| 21035 // Test access using Object.setPrototypeOf reflective method. | 20657 // Test access using Object.setPrototypeOf reflective method. |
| 21036 named_access_count = 0; | 20658 access_count = 0; |
| 21037 CompileRun("Object.setPrototypeOf(friend, {});"); | 20659 CompileRun("Object.setPrototypeOf(friend, {});"); |
| 21038 CHECK_EQ(1, named_access_count); | 20660 CHECK_EQ(1, access_count); |
| 21039 CompileRun("Object.getPrototypeOf(friend);"); | 20661 CompileRun("Object.getPrototypeOf(friend);"); |
| 21040 CHECK_EQ(2, named_access_count); | 20662 CHECK_EQ(2, access_count); |
| 21041 } | 20663 } |
| 21042 | 20664 |
| 21043 | 20665 |
| 21044 TEST(CaptureStackTraceForStackOverflow) { | 20666 TEST(CaptureStackTraceForStackOverflow) { |
| 21045 v8::internal::FLAG_stack_size = 150; | 20667 v8::internal::FLAG_stack_size = 150; |
| 21046 LocalContext current; | 20668 LocalContext current; |
| 21047 v8::Isolate* isolate = current->GetIsolate(); | 20669 v8::Isolate* isolate = current->GetIsolate(); |
| 21048 v8::HandleScope scope(isolate); | 20670 v8::HandleScope scope(isolate); |
| 21049 V8::SetCaptureStackTraceForUncaughtExceptions( | 20671 V8::SetCaptureStackTraceForUncaughtExceptions( |
| 21050 true, 10, v8::StackTrace::kDetailed); | 20672 true, 10, v8::StackTrace::kDetailed); |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 21185 set->Call(x, 1, args); | 20807 set->Call(x, 1, args); |
| 21186 CHECK(v8_num(14)->Equals(get->Call(x, 0, NULL))); | 20808 CHECK(v8_num(14)->Equals(get->Call(x, 0, NULL))); |
| 21187 } | 20809 } |
| 21188 | 20810 |
| 21189 | 20811 |
| 21190 TEST(Regress411877) { | 20812 TEST(Regress411877) { |
| 21191 v8::Isolate* isolate = CcTest::isolate(); | 20813 v8::Isolate* isolate = CcTest::isolate(); |
| 21192 v8::HandleScope handle_scope(isolate); | 20814 v8::HandleScope handle_scope(isolate); |
| 21193 v8::Handle<v8::ObjectTemplate> object_template = | 20815 v8::Handle<v8::ObjectTemplate> object_template = |
| 21194 v8::ObjectTemplate::New(isolate); | 20816 v8::ObjectTemplate::New(isolate); |
| 21195 object_template->SetAccessCheckCallbacks(NamedAccessCounter, | 20817 object_template->SetAccessCheckCallbacks(AccessCounter, NULL); |
| 21196 IndexedAccessCounter); | |
| 21197 | 20818 |
| 21198 v8::Handle<Context> context = Context::New(isolate); | 20819 v8::Handle<Context> context = Context::New(isolate); |
| 21199 v8::Context::Scope context_scope(context); | 20820 v8::Context::Scope context_scope(context); |
| 21200 | 20821 |
| 21201 context->Global()->Set(v8_str("o"), object_template->NewInstance()); | 20822 context->Global()->Set(v8_str("o"), object_template->NewInstance()); |
| 21202 CompileRun("Object.getOwnPropertyNames(o)"); | 20823 CompileRun("Object.getOwnPropertyNames(o)"); |
| 21203 } | 20824 } |
| 21204 | 20825 |
| 21205 | 20826 |
| 21206 TEST(GetHiddenPropertyTableAfterAccessCheck) { | 20827 TEST(GetHiddenPropertyTableAfterAccessCheck) { |
| 21207 v8::Isolate* isolate = CcTest::isolate(); | 20828 v8::Isolate* isolate = CcTest::isolate(); |
| 21208 v8::HandleScope handle_scope(isolate); | 20829 v8::HandleScope handle_scope(isolate); |
| 21209 v8::Handle<v8::ObjectTemplate> object_template = | 20830 v8::Handle<v8::ObjectTemplate> object_template = |
| 21210 v8::ObjectTemplate::New(isolate); | 20831 v8::ObjectTemplate::New(isolate); |
| 21211 object_template->SetAccessCheckCallbacks(NamedAccessCounter, | 20832 object_template->SetAccessCheckCallbacks(AccessCounter, NULL); |
| 21212 IndexedAccessCounter); | |
| 21213 | 20833 |
| 21214 v8::Handle<Context> context = Context::New(isolate); | 20834 v8::Handle<Context> context = Context::New(isolate); |
| 21215 v8::Context::Scope context_scope(context); | 20835 v8::Context::Scope context_scope(context); |
| 21216 | 20836 |
| 21217 v8::Handle<v8::Object> obj = object_template->NewInstance(); | 20837 v8::Handle<v8::Object> obj = object_template->NewInstance(); |
| 21218 obj->Set(v8_str("key"), v8_str("value")); | 20838 obj->Set(v8_str("key"), v8_str("value")); |
| 21219 obj->Delete(v8_str("key")); | 20839 obj->Delete(v8_str("key")); |
| 21220 | 20840 |
| 21221 obj->SetHiddenValue(v8_str("hidden key 2"), v8_str("hidden value 2")); | 20841 obj->SetHiddenValue(v8_str("hidden key 2"), v8_str("hidden value 2")); |
| 21222 } | 20842 } |
| 21223 | 20843 |
| 21224 | 20844 |
| 21225 TEST(Regress411793) { | 20845 TEST(Regress411793) { |
| 21226 v8::Isolate* isolate = CcTest::isolate(); | 20846 v8::Isolate* isolate = CcTest::isolate(); |
| 21227 v8::HandleScope handle_scope(isolate); | 20847 v8::HandleScope handle_scope(isolate); |
| 21228 v8::Handle<v8::ObjectTemplate> object_template = | 20848 v8::Handle<v8::ObjectTemplate> object_template = |
| 21229 v8::ObjectTemplate::New(isolate); | 20849 v8::ObjectTemplate::New(isolate); |
| 21230 object_template->SetAccessCheckCallbacks(NamedAccessCounter, | 20850 object_template->SetAccessCheckCallbacks(AccessCounter, NULL); |
| 21231 IndexedAccessCounter); | |
| 21232 | 20851 |
| 21233 v8::Handle<Context> context = Context::New(isolate); | 20852 v8::Handle<Context> context = Context::New(isolate); |
| 21234 v8::Context::Scope context_scope(context); | 20853 v8::Context::Scope context_scope(context); |
| 21235 | 20854 |
| 21236 context->Global()->Set(v8_str("o"), object_template->NewInstance()); | 20855 context->Global()->Set(v8_str("o"), object_template->NewInstance()); |
| 21237 CompileRun( | 20856 CompileRun( |
| 21238 "Object.defineProperty(o, 'key', " | 20857 "Object.defineProperty(o, 'key', " |
| 21239 " { get: function() {}, set: function() {} });"); | 20858 " { get: function() {}, set: function() {} });"); |
| 21240 } | 20859 } |
| 21241 | 20860 |
| (...skipping 584 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 21826 | 21445 |
| 21827 | 21446 |
| 21828 TEST(GetPrototypeAccessControl) { | 21447 TEST(GetPrototypeAccessControl) { |
| 21829 i::FLAG_allow_natives_syntax = true; | 21448 i::FLAG_allow_natives_syntax = true; |
| 21830 v8::Isolate* isolate = CcTest::isolate(); | 21449 v8::Isolate* isolate = CcTest::isolate(); |
| 21831 v8::HandleScope handle_scope(isolate); | 21450 v8::HandleScope handle_scope(isolate); |
| 21832 LocalContext env; | 21451 LocalContext env; |
| 21833 | 21452 |
| 21834 v8::Handle<v8::ObjectTemplate> obj_template = | 21453 v8::Handle<v8::ObjectTemplate> obj_template = |
| 21835 v8::ObjectTemplate::New(isolate); | 21454 v8::ObjectTemplate::New(isolate); |
| 21836 obj_template->SetAccessCheckCallbacks(BlockEverythingNamed, | 21455 obj_template->SetAccessCheckCallbacks(AccessAlwaysBlocked, NULL); |
| 21837 BlockEverythingIndexed); | |
| 21838 | 21456 |
| 21839 env->Global()->Set(v8_str("prohibited"), obj_template->NewInstance()); | 21457 env->Global()->Set(v8_str("prohibited"), obj_template->NewInstance()); |
| 21840 | 21458 |
| 21841 { | 21459 { |
| 21842 v8::TryCatch try_catch; | 21460 v8::TryCatch try_catch; |
| 21843 CompileRun( | 21461 CompileRun( |
| 21844 "function f() { %_GetPrototype(prohibited); }" | 21462 "function f() { %_GetPrototype(prohibited); }" |
| 21845 "%OptimizeFunctionOnNextCall(f);" | 21463 "%OptimizeFunctionOnNextCall(f);" |
| 21846 "f();"); | 21464 "f();"); |
| 21847 CHECK(try_catch.HasCaught()); | 21465 CHECK(try_catch.HasCaught()); |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 21939 } | 21557 } |
| 21940 { | 21558 { |
| 21941 v8::TryCatch try_catch; | 21559 v8::TryCatch try_catch; |
| 21942 uint16_t* data = reinterpret_cast<uint16_t*>(buffer); | 21560 uint16_t* data = reinterpret_cast<uint16_t*>(buffer); |
| 21943 CHECK(v8::String::NewFromTwoByte(isolate, data, v8::String::kNormalString, | 21561 CHECK(v8::String::NewFromTwoByte(isolate, data, v8::String::kNormalString, |
| 21944 length).IsEmpty()); | 21562 length).IsEmpty()); |
| 21945 CHECK(try_catch.HasCaught()); | 21563 CHECK(try_catch.HasCaught()); |
| 21946 } | 21564 } |
| 21947 free(buffer); | 21565 free(buffer); |
| 21948 } | 21566 } |
| OLD | NEW |