OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <stdlib.h> | 5 #include <stdlib.h> |
6 | 6 |
7 #include "test/cctest/test-api.h" | 7 #include "test/cctest/test-api.h" |
8 | 8 |
9 #include "include/v8-util.h" | 9 #include "include/v8-util.h" |
10 #include "src/api.h" | 10 #include "src/api.h" |
(...skipping 2889 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2900 CHECK(result_array->Get(1)->IsString()); | 2900 CHECK(result_array->Get(1)->IsString()); |
2901 CHECK(v8_str("7")->Equals(result_array->Get(0))); | 2901 CHECK(v8_str("7")->Equals(result_array->Get(0))); |
2902 CHECK(v8_str("x")->Equals(result_array->Get(1))); | 2902 CHECK(v8_str("x")->Equals(result_array->Get(1))); |
2903 | 2903 |
2904 result = CompileRun("Object.getOwnPropertySymbols(object)"); | 2904 result = CompileRun("Object.getOwnPropertySymbols(object)"); |
2905 CHECK(result->IsArray()); | 2905 CHECK(result->IsArray()); |
2906 result_array = v8::Handle<v8::Array>::Cast(result); | 2906 result_array = v8::Handle<v8::Array>::Cast(result); |
2907 CHECK_EQ(1u, result_array->Length()); | 2907 CHECK_EQ(1u, result_array->Length()); |
2908 CHECK(result_array->Get(0)->Equals(v8::Symbol::GetIterator(isolate))); | 2908 CHECK(result_array->Get(0)->Equals(v8::Symbol::GetIterator(isolate))); |
2909 } | 2909 } |
| 2910 |
| 2911 |
| 2912 namespace { |
| 2913 |
| 2914 template <typename T> |
| 2915 Local<Object> BuildWrappedObject(v8::Isolate* isolate, T* data) { |
| 2916 auto templ = v8::ObjectTemplate::New(isolate); |
| 2917 templ->SetInternalFieldCount(1); |
| 2918 auto instance = templ->NewInstance(); |
| 2919 instance->SetAlignedPointerInInternalField(0, data); |
| 2920 return instance; |
| 2921 } |
| 2922 |
| 2923 |
| 2924 template <typename T> |
| 2925 T* GetWrappedObject(Local<Value> data) { |
| 2926 return reinterpret_cast<T*>( |
| 2927 Object::Cast(*data)->GetAlignedPointerFromInternalField(0)); |
| 2928 } |
| 2929 |
| 2930 |
| 2931 struct AccessCheckData { |
| 2932 int count; |
| 2933 bool result; |
| 2934 }; |
| 2935 |
| 2936 |
| 2937 bool SimpleNamedAccessChecker(Local<v8::Object> global, Local<Value> name, |
| 2938 v8::AccessType type, Local<Value> data) { |
| 2939 auto access_check_data = GetWrappedObject<AccessCheckData>(data); |
| 2940 access_check_data->count++; |
| 2941 return access_check_data->result; |
| 2942 } |
| 2943 |
| 2944 |
| 2945 bool SimpleIndexedAccessChecker(Local<v8::Object> global, uint32_t index, |
| 2946 v8::AccessType type, Local<Value> data) { |
| 2947 auto access_check_data = GetWrappedObject<AccessCheckData>(data); |
| 2948 access_check_data->count++; |
| 2949 return access_check_data->result; |
| 2950 } |
| 2951 |
| 2952 |
| 2953 struct ShouldInterceptData { |
| 2954 int value; |
| 2955 bool should_intercept; |
| 2956 }; |
| 2957 |
| 2958 |
| 2959 void ShouldNamedInterceptor(Local<Name> name, |
| 2960 const v8::PropertyCallbackInfo<Value>& info) { |
| 2961 ApiTestFuzzer::Fuzz(); |
| 2962 CheckReturnValue(info, FUNCTION_ADDR(ShouldNamedInterceptor)); |
| 2963 auto data = GetWrappedObject<ShouldInterceptData>(info.Data()); |
| 2964 if (!data->should_intercept) return; |
| 2965 info.GetReturnValue().Set(v8_num(data->value)); |
| 2966 } |
| 2967 |
| 2968 |
| 2969 void ShouldIndexedInterceptor(uint32_t, |
| 2970 const v8::PropertyCallbackInfo<Value>& info) { |
| 2971 ApiTestFuzzer::Fuzz(); |
| 2972 CheckReturnValue(info, FUNCTION_ADDR(ShouldIndexedInterceptor)); |
| 2973 auto data = GetWrappedObject<ShouldInterceptData>(info.Data()); |
| 2974 if (!data->should_intercept) return; |
| 2975 info.GetReturnValue().Set(v8_num(data->value)); |
| 2976 } |
| 2977 |
| 2978 } // namespace |
| 2979 |
| 2980 |
| 2981 THREADED_TEST(NamedAllCanReadInterceptor) { |
| 2982 auto isolate = CcTest::isolate(); |
| 2983 v8::HandleScope handle_scope(isolate); |
| 2984 LocalContext context; |
| 2985 |
| 2986 AccessCheckData access_check_data; |
| 2987 access_check_data.result = false; |
| 2988 access_check_data.count = 0; |
| 2989 |
| 2990 ShouldInterceptData intercept_data_0; |
| 2991 intercept_data_0.value = 239; |
| 2992 intercept_data_0.should_intercept = true; |
| 2993 |
| 2994 ShouldInterceptData intercept_data_1; |
| 2995 intercept_data_1.value = 165; |
| 2996 intercept_data_1.should_intercept = false; |
| 2997 |
| 2998 auto intercepted_0 = v8::ObjectTemplate::New(isolate); |
| 2999 { |
| 3000 v8::NamedPropertyHandlerConfiguration conf(ShouldNamedInterceptor); |
| 3001 conf.flags = v8::PropertyHandlerFlags::kAllCanRead; |
| 3002 conf.data = |
| 3003 BuildWrappedObject<ShouldInterceptData>(isolate, &intercept_data_0); |
| 3004 intercepted_0->SetHandler(conf); |
| 3005 } |
| 3006 |
| 3007 auto intercepted_1 = v8::ObjectTemplate::New(isolate); |
| 3008 { |
| 3009 v8::NamedPropertyHandlerConfiguration conf(ShouldNamedInterceptor); |
| 3010 conf.flags = v8::PropertyHandlerFlags::kAllCanRead; |
| 3011 conf.data = |
| 3012 BuildWrappedObject<ShouldInterceptData>(isolate, &intercept_data_1); |
| 3013 intercepted_1->SetHandler(conf); |
| 3014 } |
| 3015 |
| 3016 auto checked = v8::ObjectTemplate::New(isolate); |
| 3017 checked->SetAccessCheckCallbacks( |
| 3018 SimpleNamedAccessChecker, nullptr, |
| 3019 BuildWrappedObject<AccessCheckData>(isolate, &access_check_data), false); |
| 3020 |
| 3021 context->Global()->Set(v8_str("intercepted_0"), intercepted_0->NewInstance()); |
| 3022 context->Global()->Set(v8_str("intercepted_1"), intercepted_1->NewInstance()); |
| 3023 auto checked_instance = checked->NewInstance(); |
| 3024 checked_instance->Set(v8_str("whatever"), v8_num(17)); |
| 3025 context->Global()->Set(v8_str("checked"), checked_instance); |
| 3026 CompileRun( |
| 3027 "checked.__proto__ = intercepted_1;" |
| 3028 "intercepted_1.__proto__ = intercepted_0;"); |
| 3029 |
| 3030 checked_instance->TurnOnAccessCheck(); |
| 3031 CHECK_EQ(0, access_check_data.count); |
| 3032 |
| 3033 access_check_data.result = true; |
| 3034 ExpectInt32("checked.whatever", 17); |
| 3035 CHECK_EQ(1, access_check_data.count); |
| 3036 |
| 3037 access_check_data.result = false; |
| 3038 ExpectInt32("checked.whatever", intercept_data_0.value); |
| 3039 CHECK_EQ(2, access_check_data.count); |
| 3040 |
| 3041 intercept_data_1.should_intercept = true; |
| 3042 ExpectInt32("checked.whatever", intercept_data_1.value); |
| 3043 CHECK_EQ(3, access_check_data.count); |
| 3044 } |
| 3045 |
| 3046 |
| 3047 THREADED_TEST(IndexedAllCanReadInterceptor) { |
| 3048 auto isolate = CcTest::isolate(); |
| 3049 v8::HandleScope handle_scope(isolate); |
| 3050 LocalContext context; |
| 3051 |
| 3052 AccessCheckData access_check_data; |
| 3053 access_check_data.result = false; |
| 3054 access_check_data.count = 0; |
| 3055 |
| 3056 ShouldInterceptData intercept_data_0; |
| 3057 intercept_data_0.value = 239; |
| 3058 intercept_data_0.should_intercept = true; |
| 3059 |
| 3060 ShouldInterceptData intercept_data_1; |
| 3061 intercept_data_1.value = 165; |
| 3062 intercept_data_1.should_intercept = false; |
| 3063 |
| 3064 auto intercepted_0 = v8::ObjectTemplate::New(isolate); |
| 3065 { |
| 3066 v8::IndexedPropertyHandlerConfiguration conf(ShouldIndexedInterceptor); |
| 3067 conf.flags = v8::PropertyHandlerFlags::kAllCanRead; |
| 3068 conf.data = |
| 3069 BuildWrappedObject<ShouldInterceptData>(isolate, &intercept_data_0); |
| 3070 intercepted_0->SetHandler(conf); |
| 3071 } |
| 3072 |
| 3073 auto intercepted_1 = v8::ObjectTemplate::New(isolate); |
| 3074 { |
| 3075 v8::IndexedPropertyHandlerConfiguration conf(ShouldIndexedInterceptor); |
| 3076 conf.flags = v8::PropertyHandlerFlags::kAllCanRead; |
| 3077 conf.data = |
| 3078 BuildWrappedObject<ShouldInterceptData>(isolate, &intercept_data_1); |
| 3079 intercepted_1->SetHandler(conf); |
| 3080 } |
| 3081 |
| 3082 auto checked = v8::ObjectTemplate::New(isolate); |
| 3083 checked->SetAccessCheckCallbacks( |
| 3084 nullptr, SimpleIndexedAccessChecker, |
| 3085 BuildWrappedObject<AccessCheckData>(isolate, &access_check_data), false); |
| 3086 |
| 3087 context->Global()->Set(v8_str("intercepted_0"), intercepted_0->NewInstance()); |
| 3088 context->Global()->Set(v8_str("intercepted_1"), intercepted_1->NewInstance()); |
| 3089 auto checked_instance = checked->NewInstance(); |
| 3090 context->Global()->Set(v8_str("checked"), checked_instance); |
| 3091 checked_instance->Set(15, v8_num(17)); |
| 3092 CompileRun( |
| 3093 "checked.__proto__ = intercepted_1;" |
| 3094 "intercepted_1.__proto__ = intercepted_0;"); |
| 3095 |
| 3096 checked_instance->TurnOnAccessCheck(); |
| 3097 CHECK_EQ(0, access_check_data.count); |
| 3098 |
| 3099 access_check_data.result = true; |
| 3100 ExpectInt32("checked[15]", 17); |
| 3101 CHECK_EQ(1, access_check_data.count); |
| 3102 |
| 3103 access_check_data.result = false; |
| 3104 ExpectInt32("checked[15]", intercept_data_0.value); |
| 3105 CHECK_EQ(2, access_check_data.count); |
| 3106 |
| 3107 intercept_data_1.should_intercept = true; |
| 3108 ExpectInt32("checked[15]", intercept_data_1.value); |
| 3109 CHECK_EQ(3, access_check_data.count); |
| 3110 } |
OLD | NEW |