| 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 2322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2333 LocalContext env(NULL, global_template); | 2333 LocalContext env(NULL, global_template); |
| 2334 v8::Handle<v8::Object> global_proxy = env->Global(); | 2334 v8::Handle<v8::Object> global_proxy = env->Global(); |
| 2335 v8::Handle<v8::Object> global = global_proxy->GetPrototype().As<v8::Object>(); | 2335 v8::Handle<v8::Object> global = global_proxy->GetPrototype().As<v8::Object>(); |
| 2336 CHECK_EQ(1, global->InternalFieldCount()); | 2336 CHECK_EQ(1, global->InternalFieldCount()); |
| 2337 CHECK(global->GetInternalField(0)->IsUndefined()); | 2337 CHECK(global->GetInternalField(0)->IsUndefined()); |
| 2338 global->SetInternalField(0, v8_num(17)); | 2338 global->SetInternalField(0, v8_num(17)); |
| 2339 CHECK_EQ(17, global->GetInternalField(0)->Int32Value()); | 2339 CHECK_EQ(17, global->GetInternalField(0)->Int32Value()); |
| 2340 } | 2340 } |
| 2341 | 2341 |
| 2342 | 2342 |
| 2343 THREADED_TEST(GlobalObjectHasRealIndexedProperty) { |
| 2344 LocalContext env; |
| 2345 v8::HandleScope scope(v8::Isolate::GetCurrent()); |
| 2346 |
| 2347 v8::Local<v8::Object> global = env->Global(); |
| 2348 global->Set(0, v8::String::New("value")); |
| 2349 CHECK(global->HasRealIndexedProperty(0)); |
| 2350 } |
| 2351 |
| 2352 |
| 2343 static void CheckAlignedPointerInInternalField(Handle<v8::Object> obj, | 2353 static void CheckAlignedPointerInInternalField(Handle<v8::Object> obj, |
| 2344 void* value) { | 2354 void* value) { |
| 2345 CHECK_EQ(0, static_cast<int>(reinterpret_cast<uintptr_t>(value) & 0x1)); | 2355 CHECK_EQ(0, static_cast<int>(reinterpret_cast<uintptr_t>(value) & 0x1)); |
| 2346 obj->SetAlignedPointerInInternalField(0, value); | 2356 obj->SetAlignedPointerInInternalField(0, value); |
| 2347 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); | 2357 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 2348 CHECK_EQ(value, obj->GetAlignedPointerFromInternalField(0)); | 2358 CHECK_EQ(value, obj->GetAlignedPointerFromInternalField(0)); |
| 2349 } | 2359 } |
| 2350 | 2360 |
| 2351 | 2361 |
| 2352 THREADED_TEST(InternalFieldsAlignedPointers) { | 2362 THREADED_TEST(InternalFieldsAlignedPointers) { |
| (...skipping 17283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 19636 v8::HandleScope scope(context->GetIsolate()); | 19646 v8::HandleScope scope(context->GetIsolate()); |
| 19637 Local<Object> obj = Object::New(); | 19647 Local<Object> obj = Object::New(); |
| 19638 Local<String> key = String::New("key"); | 19648 Local<String> key = String::New("key"); |
| 19639 obj->SetHiddenValue(key, v8::Undefined()); | 19649 obj->SetHiddenValue(key, v8::Undefined()); |
| 19640 Local<Value> value = obj->GetHiddenValue(key); | 19650 Local<Value> value = obj->GetHiddenValue(key); |
| 19641 CHECK(!value.IsEmpty()); | 19651 CHECK(!value.IsEmpty()); |
| 19642 CHECK(value->IsUndefined()); | 19652 CHECK(value->IsUndefined()); |
| 19643 } | 19653 } |
| 19644 | 19654 |
| 19645 | 19655 |
| 19656 THREADED_TEST(Regress260106) { |
| 19657 LocalContext context; |
| 19658 v8::HandleScope scope(context->GetIsolate()); |
| 19659 Local<FunctionTemplate> templ = FunctionTemplate::New(DummyCallHandler); |
| 19660 CompileRun("for (var i = 0; i < 128; i++) Object.prototype[i] = 0;"); |
| 19661 Local<Function> function = templ->GetFunction(); |
| 19662 CHECK(!function.IsEmpty()); |
| 19663 CHECK(function->IsFunction()); |
| 19664 } |
| 19665 |
| 19666 |
| 19646 #ifndef WIN32 | 19667 #ifndef WIN32 |
| 19647 class ThreadInterruptTest { | 19668 class ThreadInterruptTest { |
| 19648 public: | 19669 public: |
| 19649 ThreadInterruptTest() : sem_(NULL), sem_value_(0) { } | 19670 ThreadInterruptTest() : sem_(NULL), sem_value_(0) { } |
| 19650 ~ThreadInterruptTest() { delete sem_; } | 19671 ~ThreadInterruptTest() { delete sem_; } |
| 19651 | 19672 |
| 19652 void RunTest() { | 19673 void RunTest() { |
| 19653 sem_ = i::OS::CreateSemaphore(0); | 19674 sem_ = i::OS::CreateSemaphore(0); |
| 19654 | 19675 |
| 19655 InterruptThread i_thread(this); | 19676 InterruptThread i_thread(this); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 19698 | 19719 |
| 19699 i::Semaphore* sem_; | 19720 i::Semaphore* sem_; |
| 19700 volatile int sem_value_; | 19721 volatile int sem_value_; |
| 19701 }; | 19722 }; |
| 19702 | 19723 |
| 19703 | 19724 |
| 19704 THREADED_TEST(SemaphoreInterruption) { | 19725 THREADED_TEST(SemaphoreInterruption) { |
| 19705 ThreadInterruptTest().RunTest(); | 19726 ThreadInterruptTest().RunTest(); |
| 19706 } | 19727 } |
| 19707 | 19728 |
| 19729 |
| 19730 static bool NamedAccessAlwaysBlocked(Local<v8::Object> global, |
| 19731 Local<Value> name, |
| 19732 v8::AccessType type, |
| 19733 Local<Value> data) { |
| 19734 i::PrintF("Named access blocked.\n"); |
| 19735 return false; |
| 19736 } |
| 19737 |
| 19738 |
| 19739 static bool IndexAccessAlwaysBlocked(Local<v8::Object> global, |
| 19740 uint32_t key, |
| 19741 v8::AccessType type, |
| 19742 Local<Value> data) { |
| 19743 i::PrintF("Indexed access blocked.\n"); |
| 19744 return false; |
| 19745 } |
| 19746 |
| 19747 |
| 19748 void UnreachableCallback(const v8::FunctionCallbackInfo<v8::Value>& args) { |
| 19749 CHECK(false); |
| 19750 } |
| 19751 |
| 19752 |
| 19753 TEST(JSONStringifyAccessCheck) { |
| 19754 v8::V8::Initialize(); |
| 19755 v8::HandleScope scope(v8::Isolate::GetCurrent()); |
| 19756 |
| 19757 // Create an ObjectTemplate for global objects and install access |
| 19758 // check callbacks that will block access. |
| 19759 v8::Handle<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New(); |
| 19760 global_template->SetAccessCheckCallbacks(NamedAccessAlwaysBlocked, |
| 19761 IndexAccessAlwaysBlocked); |
| 19762 |
| 19763 // Create a context and set an x property on it's global object. |
| 19764 LocalContext context0(NULL, global_template); |
| 19765 v8::Handle<v8::Object> global0 = context0->Global(); |
| 19766 global0->Set(v8_str("x"), v8_num(42)); |
| 19767 ExpectString("JSON.stringify(this)", "{\"x\":42}"); |
| 19768 |
| 19769 for (int i = 0; i < 2; i++) { |
| 19770 if (i == 1) { |
| 19771 // Install a toJSON function on the second run. |
| 19772 v8::Handle<v8::FunctionTemplate> toJSON = |
| 19773 v8::FunctionTemplate::New(UnreachableCallback); |
| 19774 |
| 19775 global0->Set(v8_str("toJSON"), toJSON->GetFunction()); |
| 19776 } |
| 19777 // Create a context with a different security token so that the |
| 19778 // failed access check callback will be called on each access. |
| 19779 LocalContext context1(NULL, global_template); |
| 19780 context1->Global()->Set(v8_str("other"), global0); |
| 19781 |
| 19782 ExpectString("JSON.stringify(other)", "{}"); |
| 19783 ExpectString("JSON.stringify({ 'a' : other, 'b' : ['c'] })", |
| 19784 "{\"a\":{},\"b\":[\"c\"]}"); |
| 19785 ExpectString("JSON.stringify([other, 'b', 'c'])", |
| 19786 "[{},\"b\",\"c\"]"); |
| 19787 |
| 19788 v8::Handle<v8::Array> array = v8::Array::New(2); |
| 19789 array->Set(0, v8_str("a")); |
| 19790 array->Set(1, v8_str("b")); |
| 19791 context1->Global()->Set(v8_str("array"), array); |
| 19792 ExpectString("JSON.stringify(array)", "[\"a\",\"b\"]"); |
| 19793 array->TurnOnAccessCheck(); |
| 19794 ExpectString("JSON.stringify(array)", "[]"); |
| 19795 ExpectString("JSON.stringify([array])", "[[]]"); |
| 19796 ExpectString("JSON.stringify({'a' : array})", "{\"a\":[]}"); |
| 19797 } |
| 19798 } |
| 19799 |
| 19800 |
| 19801 bool access_check_fail_thrown = false; |
| 19802 bool catch_callback_called = false; |
| 19803 |
| 19804 |
| 19805 // Failed access check callback that performs a GC on each invocation. |
| 19806 void FailedAccessCheckThrows(Local<v8::Object> target, |
| 19807 v8::AccessType type, |
| 19808 Local<v8::Value> data) { |
| 19809 access_check_fail_thrown = true; |
| 19810 i::PrintF("Access check failed. Error thrown.\n"); |
| 19811 v8::ThrowException(v8::Exception::Error(v8_str("cross context"))); |
| 19812 } |
| 19813 |
| 19814 |
| 19815 void CatcherCallback(const v8::FunctionCallbackInfo<v8::Value>& args) { |
| 19816 for (int i = 0; i < args.Length(); i++) { |
| 19817 i::PrintF("%s\n", *String::Utf8Value(args[i])); |
| 19818 } |
| 19819 catch_callback_called = true; |
| 19820 } |
| 19821 |
| 19822 |
| 19823 void HasOwnPropertyCallback(const v8::FunctionCallbackInfo<v8::Value>& args) { |
| 19824 args[0]->ToObject()->HasOwnProperty(args[1]->ToString()); |
| 19825 } |
| 19826 |
| 19827 |
| 19828 void CheckCorrectThrow(const char* script) { |
| 19829 // Test that the script, when wrapped into a try-catch, triggers the catch |
| 19830 // clause due to failed access check throwing an exception. |
| 19831 // The subsequent try-catch should run without any exception. |
| 19832 access_check_fail_thrown = false; |
| 19833 catch_callback_called = false; |
| 19834 i::ScopedVector<char> source(1024); |
| 19835 i::OS::SNPrintF(source, "try { %s; } catch (e) { catcher(e); }", script); |
| 19836 CompileRun(source.start()); |
| 19837 CHECK(access_check_fail_thrown); |
| 19838 CHECK(catch_callback_called); |
| 19839 |
| 19840 access_check_fail_thrown = false; |
| 19841 catch_callback_called = false; |
| 19842 CompileRun("try { [1, 2, 3].sort(); } catch (e) { catcher(e) };"); |
| 19843 CHECK(!access_check_fail_thrown); |
| 19844 CHECK(!catch_callback_called); |
| 19845 } |
| 19846 |
| 19847 |
| 19848 TEST(AccessCheckThrows) { |
| 19849 i::FLAG_allow_natives_syntax = true; |
| 19850 v8::V8::Initialize(); |
| 19851 v8::V8::SetFailedAccessCheckCallbackFunction(&FailedAccessCheckThrows); |
| 19852 v8::HandleScope scope(v8::Isolate::GetCurrent()); |
| 19853 |
| 19854 // Create an ObjectTemplate for global objects and install access |
| 19855 // check callbacks that will block access. |
| 19856 v8::Handle<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New(); |
| 19857 global_template->SetAccessCheckCallbacks(NamedAccessAlwaysBlocked, |
| 19858 IndexAccessAlwaysBlocked); |
| 19859 |
| 19860 // Create a context and set an x property on it's global object. |
| 19861 LocalContext context0(NULL, global_template); |
| 19862 context0->Global()->Set(v8_str("x"), v8_num(42)); |
| 19863 v8::Handle<v8::Object> global0 = context0->Global(); |
| 19864 |
| 19865 // Create a context with a different security token so that the |
| 19866 // failed access check callback will be called on each access. |
| 19867 LocalContext context1(NULL, global_template); |
| 19868 context1->Global()->Set(v8_str("other"), global0); |
| 19869 |
| 19870 v8::Handle<v8::FunctionTemplate> catcher_fun = |
| 19871 v8::FunctionTemplate::New(CatcherCallback); |
| 19872 context1->Global()->Set(v8_str("catcher"), catcher_fun->GetFunction()); |
| 19873 |
| 19874 v8::Handle<v8::FunctionTemplate> has_own_property_fun = |
| 19875 v8::FunctionTemplate::New(HasOwnPropertyCallback); |
| 19876 context1->Global()->Set(v8_str("has_own_property"), |
| 19877 has_own_property_fun->GetFunction()); |
| 19878 |
| 19879 { v8::TryCatch try_catch; |
| 19880 access_check_fail_thrown = false; |
| 19881 CompileRun("other.x;"); |
| 19882 CHECK(access_check_fail_thrown); |
| 19883 CHECK(try_catch.HasCaught()); |
| 19884 } |
| 19885 |
| 19886 CheckCorrectThrow("other.x"); |
| 19887 CheckCorrectThrow("other[1]"); |
| 19888 CheckCorrectThrow("JSON.stringify(other)"); |
| 19889 CheckCorrectThrow("has_own_property(other, 'x')"); |
| 19890 CheckCorrectThrow("%GetProperty(other, 'x')"); |
| 19891 CheckCorrectThrow("%SetProperty(other, 'x', 'foo', 1, 0)"); |
| 19892 CheckCorrectThrow("%IgnoreAttributesAndSetProperty(other, 'x', 'foo')"); |
| 19893 CheckCorrectThrow("%DeleteProperty(other, 'x', 0)"); |
| 19894 CheckCorrectThrow("%DeleteProperty(other, '1', 0)"); |
| 19895 CheckCorrectThrow("%HasLocalProperty(other, 'x')"); |
| 19896 CheckCorrectThrow("%HasProperty(other, 'x')"); |
| 19897 CheckCorrectThrow("%HasElement(other, 1)"); |
| 19898 CheckCorrectThrow("%IsPropertyEnumerable(other, 'x')"); |
| 19899 CheckCorrectThrow("%GetPropertyNames(other)"); |
| 19900 CheckCorrectThrow("%GetLocalPropertyNames(other, true)"); |
| 19901 CheckCorrectThrow("%DefineOrRedefineAccessorProperty(" |
| 19902 "other, 'x', null, null, 1)"); |
| 19903 } |
| 19904 |
| 19708 #endif // WIN32 | 19905 #endif // WIN32 |
| OLD | NEW |