thanks. But in Modification Two,  I changed object x 's property a in a 
different context successfully. is this fulfilled "Access checks are 
invoked when trying to access objects" condition?

在 2018年5月30日星期三 UTC+8下午5:32:55,Ben Noordhuis写道:
>
> On Wed, May 30, 2018 at 9:32 AM,  <fengx...@gmail.com <javascript:>> 
> wrote: 
> > I try to understand SetSecurityToken's function. So I modified 
> > EvalInAccessCheckedContext test case in test-api.cc which is included in 
> v8 
> > sourcecode. Follow is my modification. 
> > 
> > Modification One: 
> > 
> > TEST(EvalInAccessCheckedContext) { 
> >   v8::Isolate* isolate = CcTest::isolate(); 
> >   v8::HandleScope scope(isolate); 
> > 
> >   v8::Local<v8::ObjectTemplate> obj_template = 
> > v8::ObjectTemplate::New(isolate); 
> > 
> >   //obj_template->SetAccessCheckCallback(AccessAlwaysAllowed); //comment 
> > this line to ensure cross access only be controlled by SetSecurityToken 
> > 
> >   v8::Local<Context> context0 = Context::New(isolate, NULL, 
> obj_template); 
> >   v8::Local<Context> context1 = Context::New(isolate, NULL, 
> obj_template); 
> > 
> >   Local<Value> foo = v8_str("foo"); 
> >   Local<Value> bar = v8_str("bar"); 
> > 
> >   // Set to different domains. 
> >   context0->SetSecurityToken(foo); 
> >   context1->SetSecurityToken(bar); 
> > 
> >   // Set up function in context0 that uses eval from context0. 
> >   context0->Enter(); 
> >   v8::Local<v8::Value> fun = CompileRun( 
> >       "var x = 42;" 
> >       "(function() {" 
> >       "  var e = eval;" 
> >       //"  return function(s) { return e(s); }" // this line will fail 
> test 
> > because SecurityToken is not the same 
> >       "  return function(s) { return eval(s); }" //  this line will pass 
> > test. but why? 
> >       "})()"); 
> >   context0->Exit(); 
> > 
> >   // Put the function into context1 and call it. Since the access check 
> >   // callback always returns true, the call succeeds even though the 
> tokens 
> >   // are different. 
> >   context1->Enter(); 
> >   context1->Global()->Set(context1, v8_str("fun"), fun).FromJust(); 
> >   v8::Local<v8::Value> x_value = CompileRun("fun('x')"); 
> >   CHECK_EQ(42, x_value->Int32Value(context1).FromJust()); 
> >   context1->Exit(); 
> > } 
> > 
> > 
> > Modification Two: 
> > 
> > TEST(EvalInAccessCheckedContext) { 
> >   v8::Isolate* isolate = CcTest::isolate(); 
> >   v8::HandleScope scope(isolate); 
> > 
> >   v8::Local<v8::ObjectTemplate> obj_template = 
> > v8::ObjectTemplate::New(isolate); 
> > 
> >   //obj_template->SetAccessCheckCallback(AccessAlwaysAllowed); //comment 
> > this line to ensure cross access only be controlled by SetSecurityToken 
> > 
> >   v8::Local<Context> context0 = Context::New(isolate, NULL, 
> obj_template); 
> >   v8::Local<Context> context1 = Context::New(isolate, NULL, 
> obj_template); 
> > 
> >   Local<Value> foo = v8_str("foo"); 
> >   Local<Value> bar = v8_str("bar"); 
> > 
> >   // Set to different domains. 
> >   context0->SetSecurityToken(foo); 
> >   context1->SetSecurityToken(bar); 
> > 
> >   // Set up function in context0 that uses eval from context0. 
> >   context0->Enter(); 
> > 
> >   v8::Local<v8::Value> fun = CompileRun( 
> >       "var x = {a:42};" 
> >       "(function() {" 
> >       "  var e = eval;" 
> >       "  return function(s) { return x; }" // just return a object 
> that's 
> > defined in context0 
> >       "})()"); 
> > 
> >   v8::Local<v8::Value> x_value0 = CompileRun("x.a"); 
> >   CHECK_EQ(42, x_value0->Int32Value(context0).FromJust()); 
> > 
> >   Local<v8::Object> obj = context0->Global()->Get(context0, 
> > v8_str("x")).ToLocalChecked()->ToObject(); 
> >   obj->Set(context0, v8_str("a"), 
> v8::Integer::New(context0->GetIsolate(), 
> > 100)).FromJust(); 
> >   context0->Global()->Set(context0, v8_str("fun"), fun).FromJust(); 
> >   v8::Local<v8::Value> x_value00 = CompileRun("fun('x')"); 
> >   CHECK_EQ(100, x_value00->ToObject()->Get(context0, 
> > v8_str("a")).ToLocalChecked()->Int32Value(context0).FromJust()); 
> > 
> >   context0->Exit(); 
> > 
> >   // Put the function into context1 and call it. Since the access check 
> >   // callback always returns true, the call succeeds even though the 
> tokens 
> >   // are different. 
> >   context1->Enter(); 
> > 
> >   context1->Global()->Set(context1, v8_str("fun"), fun).FromJust(); 
> >   v8::Local<v8::Value> x_value = CompileRun("fun('x')"); 
> >   CHECK_EQ(100, x_value->ToObject()->Get(context1, 
> > v8_str("a")).ToLocalChecked()->Int32Value(context1).FromJust()); 
> > 
> >   x_value->ToObject()->Set(context1, v8_str("a"), 
> > v8::Integer::New(context0->GetIsolate(), 102)).FromJust();// change x 
> object 
> > of context0 in context1 
> >   context1->Exit(); 
> > 
> >   context0->Enter(); 
> >   { 
> >       Local<v8::Object> obj = context0->Global()->Get(context0, 
> > v8_str("x")).ToLocalChecked()->ToObject(); 
> >       CHECK_EQ(102, obj->Get(context0, 
> > v8_str("a")).ToLocalChecked()->Int32Value(context0).FromJust()); // this 
> > will pass. so why change is allowed? 
> > 
> >       v8::Local<v8::Value> x_value00 = CompileRun("fun('x')"); 
> >       CHECK_EQ(102, x_value00->ToObject()->Get(context0, 
> > v8_str("a")).ToLocalChecked()->Int32Value(context0).FromJust()); 
> >   } 
> >   context0->Exit(); 
> > } 
>
> Is your question why direct eval() works but indirect eval() doesn't 
> with different security tokens? 
>
> It's because direct eval() isn't really a function, it's closer to a 
> keyword.  It has to be because of its runtime semantics of evaluating 
> the string in the context of the surrounding code.  Indirect eval() 
> however is a regular function that is subject to access checks. 
>
> Access checks are invoked when trying to access objects.  Context A 
> can pass on objects from context B as long as it doesn't access it, 
> where access = read or write properties, invoke the [[Call]] operation 
> of function objects, etc. 
>

-- 
-- 
v8-users mailing list
v8-users@googlegroups.com
http://groups.google.com/group/v8-users
--- 
You received this message because you are subscribed to the Google Groups 
"v8-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to v8-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to