[strong] Add tests for loading from super, loading with access checks

BUG=v8:3956
LOG=N

Review URL: https://codereview.chromium.org/1219663009

Cr-Commit-Position: refs/heads/master@{#29448}
This commit is contained in:
conradw 2015-07-02 08:23:40 -07:00 committed by Commit bot
parent c8211b64cd
commit 37bf0481de
3 changed files with 261 additions and 1 deletions

View File

@ -21349,6 +21349,164 @@ TEST(SealHandleScopeNested) {
}
static bool access_was_called = false;
static bool AccessAlwaysAllowedWithFlag(Local<v8::Object> global,
Local<Value> name, v8::AccessType type,
Local<Value> data) {
access_was_called = true;
return true;
}
static bool AccessAlwaysBlockedWithFlag(Local<v8::Object> global,
Local<Value> name, v8::AccessType type,
Local<Value> data) {
access_was_called = true;
return false;
}
TEST(StrongModeAccessCheckAllowed) {
i::FLAG_strong_mode = true;
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope handle_scope(isolate);
v8::Handle<Value> value;
access_was_called = false;
v8::Handle<v8::ObjectTemplate> obj_template =
v8::ObjectTemplate::New(isolate);
obj_template->Set(v8_str("x"), v8::Integer::New(isolate, 42));
obj_template->SetAccessCheckCallbacks(AccessAlwaysAllowedWithFlag, NULL);
// Create an environment
v8::Local<Context> context0 = Context::New(isolate, NULL, obj_template);
context0->Enter();
v8::Handle<v8::Object> global0 = context0->Global();
global0->Set(v8_str("object"), obj_template->NewInstance());
{
v8::TryCatch try_catch(isolate);
value = CompileRun("'use strong'; object.x");
CHECK(!try_catch.HasCaught());
CHECK(!access_was_called);
CHECK_EQ(42, value->Int32Value());
}
{
v8::TryCatch try_catch(isolate);
value = CompileRun("'use strong'; object.foo");
CHECK(try_catch.HasCaught());
CHECK(!access_was_called);
}
{
v8::TryCatch try_catch(isolate);
value = CompileRun("'use strong'; object[10]");
CHECK(try_catch.HasCaught());
CHECK(!access_was_called);
}
// Create an environment
v8::Local<Context> context1 = Context::New(isolate);
context1->Enter();
v8::Handle<v8::Object> global1 = context1->Global();
global1->Set(v8_str("object"), obj_template->NewInstance());
{
v8::TryCatch try_catch(isolate);
value = CompileRun("'use strong'; object.x");
CHECK(!try_catch.HasCaught());
CHECK(access_was_called);
CHECK_EQ(42, value->Int32Value());
}
access_was_called = false;
{
v8::TryCatch try_catch(isolate);
value = CompileRun("'use strong'; object.foo");
CHECK(try_catch.HasCaught());
CHECK(access_was_called);
}
access_was_called = false;
{
v8::TryCatch try_catch(isolate);
value = CompileRun("'use strong'; object[10]");
CHECK(try_catch.HasCaught());
CHECK(access_was_called);
}
context1->Exit();
context0->Exit();
}
TEST(StrongModeAccessCheckBlocked) {
i::FLAG_strong_mode = true;
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope handle_scope(isolate);
v8::Handle<Value> value;
access_was_called = false;
v8::Handle<v8::ObjectTemplate> obj_template =
v8::ObjectTemplate::New(isolate);
obj_template->Set(v8_str("x"), v8::Integer::New(isolate, 42));
obj_template->SetAccessCheckCallbacks(AccessAlwaysBlockedWithFlag, NULL);
// Create an environment
v8::Local<Context> context0 = Context::New(isolate, NULL, obj_template);
context0->Enter();
v8::Handle<v8::Object> global0 = context0->Global();
global0->Set(v8_str("object"), obj_template->NewInstance());
{
v8::TryCatch try_catch(isolate);
value = CompileRun("'use strong'; object.x");
CHECK(!try_catch.HasCaught());
CHECK(!access_was_called);
CHECK_EQ(42, value->Int32Value());
}
{
v8::TryCatch try_catch(isolate);
value = CompileRun("'use strong'; object.foo");
CHECK(try_catch.HasCaught());
CHECK(!access_was_called);
}
{
v8::TryCatch try_catch(isolate);
value = CompileRun("'use strong'; object[10]");
CHECK(try_catch.HasCaught());
CHECK(!access_was_called);
}
// Create an environment
v8::Local<Context> context1 = Context::New(isolate);
context1->Enter();
v8::Handle<v8::Object> global1 = context1->Global();
global1->Set(v8_str("object"), obj_template->NewInstance());
{
v8::TryCatch try_catch(isolate);
value = CompileRun("'use strong'; object.x");
CHECK(try_catch.HasCaught());
CHECK(access_was_called);
}
access_was_called = false;
{
v8::TryCatch try_catch(isolate);
value = CompileRun("'use strong'; object.foo");
CHECK(try_catch.HasCaught());
CHECK(access_was_called);
}
access_was_called = false;
{
v8::TryCatch try_catch(isolate);
value = CompileRun("'use strong'; object[10]");
CHECK(try_catch.HasCaught());
CHECK(access_was_called);
}
context1->Exit();
context0->Exit();
}
TEST(StrongModeArityCallFromApi) {
i::FLAG_strong_mode = true;
LocalContext env;

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --strong-mode --allow-natives-syntax
// Flags: --strong-mode
function getGlobal() {
return this;

View File

@ -0,0 +1,102 @@
// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --strong-mode
"use strong";
function testSuper(object) {
assertEquals(0, object.validLoad());
assertThrows(function(){ return object.propertyLoad() }, TypeError);
assertThrows(function(){ return object.elementLoad() }, TypeError);
assertThrows(function(){ return object.accessorLoad() }, TypeError);
}
class A {
constructor() {}
foo() {
return 0;
}
get bar() {
return 0;
}
set baz(_) {
return;
}
}
class B extends A {
constructor() {
super();
}
validLoad() {
return super.foo() + super.bar;
}
propertyLoad() {
return super.x;
}
elementLoad() {
return super[1];
}
accessorLoad() {
return super.baz;
}
}
class C extends A {
constructor() {
super();
this[1] = 0;
this.x = 0;
}
get baz() {
return 0;
}
validLoad() {
return super.foo() + super.bar;
}
propertyLoad() {
return super.x;
}
elementLoad() {
return super[1];
}
accessorLoad() {
return super.baz;
}
}
let b = new B();
let c = new C();
testSuper(b);
testSuper(c);
let d = {
"0": 0,
foo: 0,
bar: (function(){return 0}),
get baz(){return 0},
set qux(_){return}
}
let e = {
__proto__: d,
"1": 0,
x: 0,
get baz(){return 0},
validLoad() {
return super[0] + super.foo + super.bar() + super.baz;
},
propertyLoad() {
return super.x;
},
elementLoad() {
return super[1];
},
accessorLoad() {
return super.qux;
}
}
testSuper(e);