Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(168)

Side by Side Diff: test/cctest/test-access-checks.cc

Issue 2107673003: Add an API to create a detached global object (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: updates Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« src/bootstrapper.cc ('K') | « src/factory.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 the V8 project authors. All rights reserved. 1 // Copyright 2016 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/cctest.h" 7 #include "test/cctest/cctest.h"
8 8
9 namespace { 9 namespace {
10 10
11 int32_t g_cross_context_int = 0; 11 int32_t g_cross_context_int = 0;
12 12
13 bool g_expect_interceptor_call = false;
14
13 void NamedGetter(v8::Local<v8::Name> property, 15 void NamedGetter(v8::Local<v8::Name> property,
14 const v8::PropertyCallbackInfo<v8::Value>& info) { 16 const v8::PropertyCallbackInfo<v8::Value>& info) {
17 CHECK(g_expect_interceptor_call);
15 v8::Isolate* isolate = info.GetIsolate(); 18 v8::Isolate* isolate = info.GetIsolate();
16 v8::Local<v8::Context> context = isolate->GetCurrentContext(); 19 v8::Local<v8::Context> context = isolate->GetCurrentContext();
17 if (property->Equals(context, v8_str("cross_context_int")).FromJust()) 20 if (property->Equals(context, v8_str("cross_context_int")).FromJust())
18 info.GetReturnValue().Set(g_cross_context_int); 21 info.GetReturnValue().Set(g_cross_context_int);
19 } 22 }
20 23
21 void NamedSetter(v8::Local<v8::Name> property, v8::Local<v8::Value> value, 24 void NamedSetter(v8::Local<v8::Name> property, v8::Local<v8::Value> value,
22 const v8::PropertyCallbackInfo<v8::Value>& info) { 25 const v8::PropertyCallbackInfo<v8::Value>& info) {
26 CHECK(g_expect_interceptor_call);
23 v8::Isolate* isolate = info.GetIsolate(); 27 v8::Isolate* isolate = info.GetIsolate();
24 v8::Local<v8::Context> context = isolate->GetCurrentContext(); 28 v8::Local<v8::Context> context = isolate->GetCurrentContext();
25 if (!property->Equals(context, v8_str("cross_context_int")).FromJust()) 29 if (!property->Equals(context, v8_str("cross_context_int")).FromJust())
26 return; 30 return;
27 if (value->IsInt32()) { 31 if (value->IsInt32()) {
28 g_cross_context_int = value->ToInt32(context).ToLocalChecked()->Value(); 32 g_cross_context_int = value->ToInt32(context).ToLocalChecked()->Value();
29 } 33 }
30 info.GetReturnValue().Set(value); 34 info.GetReturnValue().Set(value);
31 } 35 }
32 36
33 void NamedQuery(v8::Local<v8::Name> property, 37 void NamedQuery(v8::Local<v8::Name> property,
34 const v8::PropertyCallbackInfo<v8::Integer>& info) { 38 const v8::PropertyCallbackInfo<v8::Integer>& info) {
39 CHECK(g_expect_interceptor_call);
35 v8::Isolate* isolate = info.GetIsolate(); 40 v8::Isolate* isolate = info.GetIsolate();
36 v8::Local<v8::Context> context = isolate->GetCurrentContext(); 41 v8::Local<v8::Context> context = isolate->GetCurrentContext();
37 if (!property->Equals(context, v8_str("cross_context_int")).FromJust()) 42 if (!property->Equals(context, v8_str("cross_context_int")).FromJust())
38 return; 43 return;
39 info.GetReturnValue().Set(v8::DontDelete); 44 info.GetReturnValue().Set(v8::DontDelete);
40 } 45 }
41 46
42 void NamedDeleter(v8::Local<v8::Name> property, 47 void NamedDeleter(v8::Local<v8::Name> property,
43 const v8::PropertyCallbackInfo<v8::Boolean>& info) { 48 const v8::PropertyCallbackInfo<v8::Boolean>& info) {
49 CHECK(g_expect_interceptor_call);
44 v8::Isolate* isolate = info.GetIsolate(); 50 v8::Isolate* isolate = info.GetIsolate();
45 v8::Local<v8::Context> context = isolate->GetCurrentContext(); 51 v8::Local<v8::Context> context = isolate->GetCurrentContext();
46 if (!property->Equals(context, v8_str("cross_context_int")).FromJust()) 52 if (!property->Equals(context, v8_str("cross_context_int")).FromJust())
47 return; 53 return;
48 info.GetReturnValue().Set(false); 54 info.GetReturnValue().Set(false);
49 } 55 }
50 56
51 void NamedEnumerator(const v8::PropertyCallbackInfo<v8::Array>& info) { 57 void NamedEnumerator(const v8::PropertyCallbackInfo<v8::Array>& info) {
58 CHECK(g_expect_interceptor_call);
52 v8::Isolate* isolate = info.GetIsolate(); 59 v8::Isolate* isolate = info.GetIsolate();
53 v8::Local<v8::Context> context = isolate->GetCurrentContext(); 60 v8::Local<v8::Context> context = isolate->GetCurrentContext();
54 v8::Local<v8::Array> names = v8::Array::New(isolate, 1); 61 v8::Local<v8::Array> names = v8::Array::New(isolate, 1);
55 names->Set(context, 0, v8_str("cross_context_int")).FromJust(); 62 names->Set(context, 0, v8_str("cross_context_int")).FromJust();
56 info.GetReturnValue().Set(names); 63 info.GetReturnValue().Set(names);
57 } 64 }
58 65
59 void IndexedGetter(uint32_t index, 66 void IndexedGetter(uint32_t index,
60 const v8::PropertyCallbackInfo<v8::Value>& info) { 67 const v8::PropertyCallbackInfo<v8::Value>& info) {
68 CHECK(g_expect_interceptor_call);
61 if (index == 7) info.GetReturnValue().Set(g_cross_context_int); 69 if (index == 7) info.GetReturnValue().Set(g_cross_context_int);
62 } 70 }
63 71
64 void IndexedSetter(uint32_t index, v8::Local<v8::Value> value, 72 void IndexedSetter(uint32_t index, v8::Local<v8::Value> value,
65 const v8::PropertyCallbackInfo<v8::Value>& info) { 73 const v8::PropertyCallbackInfo<v8::Value>& info) {
74 CHECK(g_expect_interceptor_call);
66 v8::Isolate* isolate = info.GetIsolate(); 75 v8::Isolate* isolate = info.GetIsolate();
67 v8::Local<v8::Context> context = isolate->GetCurrentContext(); 76 v8::Local<v8::Context> context = isolate->GetCurrentContext();
68 if (index != 7) return; 77 if (index != 7) return;
69 if (value->IsInt32()) { 78 if (value->IsInt32()) {
70 g_cross_context_int = value->ToInt32(context).ToLocalChecked()->Value(); 79 g_cross_context_int = value->ToInt32(context).ToLocalChecked()->Value();
71 } 80 }
72 info.GetReturnValue().Set(value); 81 info.GetReturnValue().Set(value);
73 } 82 }
74 83
75 void IndexedQuery(uint32_t index, 84 void IndexedQuery(uint32_t index,
76 const v8::PropertyCallbackInfo<v8::Integer>& info) { 85 const v8::PropertyCallbackInfo<v8::Integer>& info) {
86 CHECK(g_expect_interceptor_call);
77 if (index == 7) info.GetReturnValue().Set(v8::DontDelete); 87 if (index == 7) info.GetReturnValue().Set(v8::DontDelete);
78 } 88 }
79 89
80 void IndexedDeleter(uint32_t index, 90 void IndexedDeleter(uint32_t index,
81 const v8::PropertyCallbackInfo<v8::Boolean>& info) { 91 const v8::PropertyCallbackInfo<v8::Boolean>& info) {
92 CHECK(g_expect_interceptor_call);
82 if (index == 7) info.GetReturnValue().Set(false); 93 if (index == 7) info.GetReturnValue().Set(false);
83 } 94 }
84 95
85 void IndexedEnumerator(const v8::PropertyCallbackInfo<v8::Array>& info) { 96 void IndexedEnumerator(const v8::PropertyCallbackInfo<v8::Array>& info) {
97 CHECK(g_expect_interceptor_call);
86 v8::Isolate* isolate = info.GetIsolate(); 98 v8::Isolate* isolate = info.GetIsolate();
87 v8::Local<v8::Context> context = isolate->GetCurrentContext(); 99 v8::Local<v8::Context> context = isolate->GetCurrentContext();
88 v8::Local<v8::Array> names = v8::Array::New(isolate, 1); 100 v8::Local<v8::Array> names = v8::Array::New(isolate, 1);
89 names->Set(context, 0, v8_str("7")).FromJust(); 101 names->Set(context, 0, v8_str("7")).FromJust();
90 info.GetReturnValue().Set(names); 102 info.GetReturnValue().Set(names);
91 } 103 }
92 104
93 bool AccessCheck(v8::Local<v8::Context> accessing_context, 105 bool AccessCheck(v8::Local<v8::Context> accessing_context,
94 v8::Local<v8::Object> accessed_object, 106 v8::Local<v8::Object> accessed_object,
95 v8::Local<v8::Value> data) { 107 v8::Local<v8::Value> data) {
96 return false; 108 return false;
97 } 109 }
98 110
99 void GetCrossContextInt(v8::Local<v8::String> property, 111 void GetCrossContextInt(v8::Local<v8::String> property,
100 const v8::PropertyCallbackInfo<v8::Value>& info) { 112 const v8::PropertyCallbackInfo<v8::Value>& info) {
113 CHECK(!g_expect_interceptor_call);
101 info.GetReturnValue().Set(g_cross_context_int); 114 info.GetReturnValue().Set(g_cross_context_int);
102 } 115 }
103 116
104 void SetCrossContextInt(v8::Local<v8::String> property, 117 void SetCrossContextInt(v8::Local<v8::String> property,
105 v8::Local<v8::Value> value, 118 v8::Local<v8::Value> value,
106 const v8::PropertyCallbackInfo<void>& info) { 119 const v8::PropertyCallbackInfo<void>& info) {
120 CHECK(!g_expect_interceptor_call);
107 v8::Isolate* isolate = info.GetIsolate(); 121 v8::Isolate* isolate = info.GetIsolate();
108 v8::Local<v8::Context> context = isolate->GetCurrentContext(); 122 v8::Local<v8::Context> context = isolate->GetCurrentContext();
109 if (value->IsInt32()) { 123 if (value->IsInt32()) {
110 g_cross_context_int = value->ToInt32(context).ToLocalChecked()->Value(); 124 g_cross_context_int = value->ToInt32(context).ToLocalChecked()->Value();
111 } 125 }
112 } 126 }
113 127
114 void Return42(v8::Local<v8::String> property, 128 void Return42(v8::Local<v8::String> property,
115 const v8::PropertyCallbackInfo<v8::Value>& info) { 129 const v8::PropertyCallbackInfo<v8::Value>& info) {
116 info.GetReturnValue().Set(42); 130 info.GetReturnValue().Set(42);
117 } 131 }
118 132
133 void CheckCanRunScriptInContext(v8::Isolate* isolate,
134 v8::Local<v8::Context> context) {
135 v8::HandleScope handle_scope(isolate);
136 v8::Context::Scope context_scope(context);
137
138 g_expect_interceptor_call = false;
139 g_cross_context_int = 0;
140
141 // Running script in this context should work.
142 CompileRunChecked(isolate, "this.foo = 42; this[23] = true;");
143 ExpectInt32("this.all_can_read", 42);
144 CompileRunChecked(isolate, "this.cross_context_int = 23");
145 CHECK_EQ(g_cross_context_int, 23);
146 ExpectInt32("this.cross_context_int", 23);
147 }
148
149 void CheckCrossContextAccess(v8::Isolate* isolate,
150 v8::Local<v8::Context> accessing_context,
151 v8::Local<v8::Object> accessed_object) {
152 v8::HandleScope handle_scope(isolate);
153 accessing_context->Global()
154 ->Set(accessing_context, v8_str("other"), accessed_object)
155 .FromJust();
156 v8::Context::Scope context_scope(accessing_context);
157
158 g_expect_interceptor_call = true;
159 g_cross_context_int = 23;
160
161 {
162 v8::TryCatch try_catch(isolate);
163 CHECK(CompileRun(accessing_context, "this.other.foo").IsEmpty());
164 }
165 {
166 v8::TryCatch try_catch(isolate);
167 CHECK(CompileRun(accessing_context, "this.other[23]").IsEmpty());
168 }
169
170 // AllCanRead properties are also inaccessible.
171 {
172 v8::TryCatch try_catch(isolate);
173 CHECK(CompileRun(accessing_context, "this.other.all_can_read").IsEmpty());
174 }
175
176 // Intercepted properties are accessible, however.
177 ExpectInt32("this.other.cross_context_int", 23);
178 CompileRunChecked(isolate, "this.other.cross_context_int = 42");
179 ExpectInt32("this.other[7]", 42);
180 ExpectString("JSON.stringify(Object.getOwnPropertyNames(this.other))",
181 "[\"7\",\"cross_context_int\"]");
182 }
183
119 } // namespace 184 } // namespace
120 185
121 TEST(AccessCheckWithInterceptor) { 186 TEST(AccessCheckWithInterceptor) {
122 v8::Isolate* isolate = CcTest::isolate(); 187 v8::Isolate* isolate = CcTest::isolate();
123 v8::HandleScope scope(isolate); 188 v8::HandleScope scope(isolate);
124 v8::Local<v8::ObjectTemplate> global_template = 189 v8::Local<v8::ObjectTemplate> global_template =
125 v8::ObjectTemplate::New(isolate); 190 v8::ObjectTemplate::New(isolate);
126 global_template->SetAccessCheckCallbackAndHandler( 191 global_template->SetAccessCheckCallbackAndHandler(
127 AccessCheck, 192 AccessCheck,
128 v8::NamedPropertyHandlerConfiguration( 193 v8::NamedPropertyHandlerConfiguration(
129 NamedGetter, NamedSetter, NamedQuery, NamedDeleter, NamedEnumerator), 194 NamedGetter, NamedSetter, NamedQuery, NamedDeleter, NamedEnumerator),
130 v8::IndexedPropertyHandlerConfiguration(IndexedGetter, IndexedSetter, 195 v8::IndexedPropertyHandlerConfiguration(IndexedGetter, IndexedSetter,
131 IndexedQuery, IndexedDeleter, 196 IndexedQuery, IndexedDeleter,
132 IndexedEnumerator)); 197 IndexedEnumerator));
133 global_template->SetNativeDataProperty( 198 global_template->SetNativeDataProperty(
134 v8_str("cross_context_int"), GetCrossContextInt, SetCrossContextInt); 199 v8_str("cross_context_int"), GetCrossContextInt, SetCrossContextInt);
135 global_template->SetNativeDataProperty( 200 global_template->SetNativeDataProperty(
136 v8_str("all_can_read"), Return42, nullptr, v8::Local<v8::Value>(), 201 v8_str("all_can_read"), Return42, nullptr, v8::Local<v8::Value>(),
137 v8::None, v8::Local<v8::AccessorSignature>(), v8::ALL_CAN_READ); 202 v8::None, v8::Local<v8::AccessorSignature>(), v8::ALL_CAN_READ);
138 203
139 v8::Local<v8::Context> context0 = 204 v8::Local<v8::Context> context0 =
140 v8::Context::New(isolate, nullptr, global_template); 205 v8::Context::New(isolate, nullptr, global_template);
141 context0->Enter(); 206 CheckCanRunScriptInContext(isolate, context0);
142
143 // Running script in this context should work.
144 CompileRunChecked(isolate, "this.foo = 42; this[23] = true;");
145 ExpectInt32("this.all_can_read", 42);
146 CompileRunChecked(isolate, "this.cross_context_int = 23");
147 CHECK_EQ(g_cross_context_int, 23);
148 ExpectInt32("this.cross_context_int", 23);
149 207
150 // Create another context. 208 // Create another context.
209 v8::Local<v8::Context> context1 =
210 v8::Context::New(isolate, nullptr, global_template);
211 CheckCrossContextAccess(isolate, context1, context0->Global());
212 }
213
214 TEST(NewRemoteContext) {
215 v8::Isolate* isolate = CcTest::isolate();
216 v8::HandleScope scope(isolate);
217 v8::Local<v8::ObjectTemplate> global_template =
218 v8::ObjectTemplate::New(isolate);
219 global_template->SetAccessCheckCallbackAndHandler(
220 AccessCheck,
221 v8::NamedPropertyHandlerConfiguration(
222 NamedGetter, NamedSetter, NamedQuery, NamedDeleter, NamedEnumerator),
223 v8::IndexedPropertyHandlerConfiguration(IndexedGetter, IndexedSetter,
224 IndexedQuery, IndexedDeleter,
225 IndexedEnumerator));
226 global_template->SetNativeDataProperty(
227 v8_str("cross_context_int"), GetCrossContextInt, SetCrossContextInt);
228 global_template->SetNativeDataProperty(
229 v8_str("all_can_read"), Return42, nullptr, v8::Local<v8::Value>(),
230 v8::None, v8::Local<v8::AccessorSignature>(), v8::ALL_CAN_READ);
231
232 v8::Local<v8::Object> global0 =
233 v8::Context::NewRemoteContext(isolate, global_template).ToLocalChecked();
234
235 // Create a real context.
151 { 236 {
152 v8::HandleScope other_scope(isolate); 237 v8::HandleScope other_scope(isolate);
153 v8::Local<v8::Context> context1 = 238 v8::Local<v8::Context> context1 =
154 v8::Context::New(isolate, nullptr, global_template); 239 v8::Context::New(isolate, nullptr, global_template);
155 context1->Global()
156 ->Set(context1, v8_str("other"), context0->Global())
157 .FromJust();
158 v8::Context::Scope context_scope(context1);
159 240
160 { 241 CheckCrossContextAccess(isolate, context1, global0);
161 v8::TryCatch try_catch(isolate); 242 }
162 CHECK(CompileRun(context1, "this.other.foo").IsEmpty());
163 }
164 {
165 v8::TryCatch try_catch(isolate);
166 CHECK(CompileRun(context1, "this.other[23]").IsEmpty());
167 }
168 243
169 // AllCanRead properties are also inaccessible. 244 // Create a context using the detached global.
170 { 245 {
171 v8::TryCatch try_catch(isolate); 246 v8::HandleScope other_scope(isolate);
172 CHECK(CompileRun(context1, "this.other.all_can_read").IsEmpty()); 247 v8::Local<v8::Context> context2 =
173 } 248 v8::Context::New(isolate, nullptr, global_template, global0);
174 249
175 // Intercepted properties are accessible, however. 250 CheckCanRunScriptInContext(isolate, context2);
176 ExpectInt32("this.other.cross_context_int", 23); 251 }
177 CompileRunChecked(isolate, "this.other.cross_context_int = 42"); 252
178 ExpectInt32("this.other[7]", 42); 253 // Turn a regular context into a remote context.
179 ExpectString("JSON.stringify(Object.getOwnPropertyNames(this.other))", 254 {
180 "[\"7\",\"cross_context_int\"]"); 255 v8::HandleScope other_scope(isolate);
256 v8::Local<v8::Context> context3 =
257 v8::Context::New(isolate, nullptr, global_template);
258
259 CheckCanRunScriptInContext(isolate, context3);
260
261 // Turn the global object into a remote context, and try to access it.
262 v8::Local<v8::Object> global3 =
263 v8::Context::NewRemoteContext(isolate, global_template,
264 context3->Global())
265 .ToLocalChecked();
266 v8::Local<v8::Context> context4 =
267 v8::Context::New(isolate, nullptr, global_template);
268
269 CheckCrossContextAccess(isolate, context4, global3);
270
271 // Turn it back into a regular context.
272 v8::Local<v8::Context> context5 =
273 v8::Context::New(isolate, nullptr, global_template, global3);
274
275 CheckCanRunScriptInContext(isolate, context5);
181 } 276 }
182 } 277 }
OLDNEW
« src/bootstrapper.cc ('K') | « src/factory.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698