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

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: 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);
(...skipping 17 matching lines...) Expand all
134 v8_str("cross_context_int"), GetCrossContextInt, SetCrossContextInt); 148 v8_str("cross_context_int"), GetCrossContextInt, SetCrossContextInt);
135 global_template->SetNativeDataProperty( 149 global_template->SetNativeDataProperty(
136 v8_str("all_can_read"), Return42, nullptr, v8::Local<v8::Value>(), 150 v8_str("all_can_read"), Return42, nullptr, v8::Local<v8::Value>(),
137 v8::None, v8::Local<v8::AccessorSignature>(), v8::ALL_CAN_READ); 151 v8::None, v8::Local<v8::AccessorSignature>(), v8::ALL_CAN_READ);
138 152
139 v8::Local<v8::Context> context0 = 153 v8::Local<v8::Context> context0 =
140 v8::Context::New(isolate, nullptr, global_template); 154 v8::Context::New(isolate, nullptr, global_template);
141 context0->Enter(); 155 context0->Enter();
142 156
143 // Running script in this context should work. 157 // Running script in this context should work.
158 g_expect_interceptor_call = false;
144 CompileRunChecked(isolate, "this.foo = 42; this[23] = true;"); 159 CompileRunChecked(isolate, "this.foo = 42; this[23] = true;");
145 ExpectInt32("this.all_can_read", 42); 160 ExpectInt32("this.all_can_read", 42);
146 CompileRunChecked(isolate, "this.cross_context_int = 23"); 161 CompileRunChecked(isolate, "this.cross_context_int = 23");
147 CHECK_EQ(g_cross_context_int, 23); 162 CHECK_EQ(g_cross_context_int, 23);
148 ExpectInt32("this.cross_context_int", 23); 163 ExpectInt32("this.cross_context_int", 23);
149 164
150 // Create another context. 165 // Create another context.
151 { 166 {
152 v8::HandleScope other_scope(isolate); 167 v8::HandleScope other_scope(isolate);
153 v8::Local<v8::Context> context1 = 168 v8::Local<v8::Context> context1 =
154 v8::Context::New(isolate, nullptr, global_template); 169 v8::Context::New(isolate, nullptr, global_template);
155 context1->Global() 170 context1->Global()
156 ->Set(context1, v8_str("other"), context0->Global()) 171 ->Set(context1, v8_str("other"), context0->Global())
157 .FromJust(); 172 .FromJust();
158 v8::Context::Scope context_scope(context1); 173 v8::Context::Scope context_scope(context1);
174 g_expect_interceptor_call = true;
159 175
160 { 176 {
161 v8::TryCatch try_catch(isolate); 177 v8::TryCatch try_catch(isolate);
178 CHECK(CompileRun(context1, "this.other.foo").IsEmpty());
179 }
180 {
181 v8::TryCatch try_catch(isolate);
182 CHECK(CompileRun(context1, "this.other[23]").IsEmpty());
183 }
184
185 // AllCanRead properties are also inaccessible.
186 {
187 v8::TryCatch try_catch(isolate);
188 CHECK(CompileRun(context1, "this.other.all_can_read").IsEmpty());
189 }
190
191 // Intercepted properties are accessible, however.
192 ExpectInt32("this.other.cross_context_int", 23);
193 CompileRunChecked(isolate, "this.other.cross_context_int = 42");
194 ExpectInt32("this.other[7]", 42);
195 ExpectString("JSON.stringify(Object.getOwnPropertyNames(this.other))",
196 "[\"7\",\"cross_context_int\"]");
197 }
198 }
199
200 TEST(NewDetachedGlobal) {
201 v8::Isolate* isolate = CcTest::isolate();
202 v8::HandleScope scope(isolate);
203 v8::Local<v8::ObjectTemplate> global_template =
204 v8::ObjectTemplate::New(isolate);
205 global_template->SetAccessCheckCallbackAndHandler(
206 AccessCheck,
207 v8::NamedPropertyHandlerConfiguration(
208 NamedGetter, NamedSetter, NamedQuery, NamedDeleter, NamedEnumerator),
209 v8::IndexedPropertyHandlerConfiguration(IndexedGetter, IndexedSetter,
210 IndexedQuery, IndexedDeleter,
211 IndexedEnumerator));
212 global_template->SetNativeDataProperty(
213 v8_str("cross_context_int"), GetCrossContextInt, SetCrossContextInt);
214 global_template->SetNativeDataProperty(
215 v8_str("all_can_read"), Return42, nullptr, v8::Local<v8::Value>(),
216 v8::None, v8::Local<v8::AccessorSignature>(), v8::ALL_CAN_READ);
217 g_cross_context_int = 23;
218
219 v8::Local<v8::Object> global0 =
220 v8::Context::NewDetachedGlobal(isolate, global_template);
221
222 // Create a real context.
223 {
224 v8::HandleScope other_scope(isolate);
225 v8::Local<v8::Context> context1 =
226 v8::Context::New(isolate, nullptr, global_template);
227 context1->Global()->Set(context1, v8_str("other"), global0).FromJust();
228 v8::Context::Scope context_scope(context1);
229 g_expect_interceptor_call = true;
230
231 {
232 v8::TryCatch try_catch(isolate);
162 CHECK(CompileRun(context1, "this.other.foo").IsEmpty()); 233 CHECK(CompileRun(context1, "this.other.foo").IsEmpty());
163 } 234 }
164 { 235 {
165 v8::TryCatch try_catch(isolate); 236 v8::TryCatch try_catch(isolate);
166 CHECK(CompileRun(context1, "this.other[23]").IsEmpty()); 237 CHECK(CompileRun(context1, "this.other[23]").IsEmpty());
167 } 238 }
168 239
169 // AllCanRead properties are also inaccessible. 240 // AllCanRead properties are also inaccessible.
170 { 241 {
171 v8::TryCatch try_catch(isolate); 242 v8::TryCatch try_catch(isolate);
172 CHECK(CompileRun(context1, "this.other.all_can_read").IsEmpty()); 243 CHECK(CompileRun(context1, "this.other.all_can_read").IsEmpty());
173 } 244 }
174 245
175 // Intercepted properties are accessible, however. 246 // Intercepted properties are accessible, however.
176 ExpectInt32("this.other.cross_context_int", 23); 247 ExpectInt32("this.other.cross_context_int", 23);
177 CompileRunChecked(isolate, "this.other.cross_context_int = 42"); 248 CompileRunChecked(isolate, "this.other.cross_context_int = 42");
178 ExpectInt32("this.other[7]", 42); 249 ExpectInt32("this.other[7]", 42);
179 ExpectString("JSON.stringify(Object.getOwnPropertyNames(this.other))", 250 ExpectString("JSON.stringify(Object.getOwnPropertyNames(this.other))",
180 "[\"7\",\"cross_context_int\"]"); 251 "[\"7\",\"cross_context_int\"]");
181 } 252 }
253
254 // Create a context using the detached global.
255 {
256 v8::HandleScope other_scope(isolate);
257 v8::Local<v8::Context> context2 =
258 v8::Context::New(isolate, nullptr, global_template, global0);
259 v8::Context::Scope context_scope(context2);
260 g_expect_interceptor_call = true;
261 g_cross_context_int = 0;
262 context2->Enter();
263
264 // Running script in this context should work.
265 g_expect_interceptor_call = false;
266 CompileRunChecked(isolate, "this.foo = 42; this[23] = true;");
267 ExpectInt32("this.all_can_read", 42);
268 CompileRunChecked(isolate, "this.cross_context_int = 23");
269 CHECK_EQ(g_cross_context_int, 23);
270 ExpectInt32("this.cross_context_int", 23);
271 }
182 } 272 }
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