Index: test/cctest/test-api.cc |
=================================================================== |
--- test/cctest/test-api.cc (revision 6626) |
+++ test/cctest/test-api.cc (working copy) |
@@ -5133,11 +5133,13 @@ |
} |
+static bool allowed_access_type[v8::ACCESS_KEYS + 1] = { false }; |
static bool NamedAccessBlocker(Local<v8::Object> global, |
Local<Value> name, |
v8::AccessType type, |
Local<Value> data) { |
- return Context::GetCurrent()->Global()->Equals(global); |
+ return Context::GetCurrent()->Global()->Equals(global) || |
+ allowed_access_type[type]; |
} |
@@ -5145,7 +5147,8 @@ |
uint32_t key, |
v8::AccessType type, |
Local<Value> data) { |
- return Context::GetCurrent()->Global()->Equals(global); |
+ return Context::GetCurrent()->Global()->Equals(global) || |
+ allowed_access_type[type]; |
} |
@@ -5177,7 +5180,7 @@ |
} |
-THREADED_TEST(AccessControl) { |
+TEST(AccessControl) { |
v8::HandleScope handle_scope; |
v8::Handle<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New(); |
@@ -5203,6 +5206,27 @@ |
v8::Handle<v8::Object> global0 = context0->Global(); |
+ // Define a property with JS getter and setter. |
+ CompileRun( |
+ "function getter() { return 'getter'; };\n" |
+ "function setter() { return 'setter'; }\n" |
+ "Object.defineProperty(this, 'js_accessor_p', {get:getter, set:setter})"); |
+ |
+ Local<Value> getter = global0->Get(v8_str("getter")); |
+ Local<Value> setter = global0->Get(v8_str("setter")); |
+ |
+ // And define normal element. |
+ global0->Set(239, v8_str("239")); |
+ |
+ // Define an element with JS getter and setter. |
+ CompileRun( |
+ "function el_getter() { return 'el_getter'; };\n" |
+ "function el_setter() { return 'el_setter'; };\n" |
+ "Object.defineProperty(this, '42', {get: el_getter, set: el_setter});"); |
+ |
+ Local<Value> el_getter = global0->Get(v8_str("el_getter")); |
+ Local<Value> el_setter = global0->Get(v8_str("el_setter")); |
+ |
v8::HandleScope scope1; |
v8::Persistent<Context> context1 = Context::New(); |
@@ -5211,20 +5235,159 @@ |
v8::Handle<v8::Object> global1 = context1->Global(); |
global1->Set(v8_str("other"), global0); |
- v8::Handle<Value> value; |
+ // Access blocked property. |
+ CompileRun("other.blocked_prop = 1"); |
- // Access blocked property |
- value = CompileRun("other.blocked_prop = 1"); |
- value = CompileRun("other.blocked_prop"); |
- CHECK(value->IsUndefined()); |
+ ExpectUndefined("other.blocked_prop"); |
+ ExpectUndefined( |
+ "Object.getOwnPropertyDescriptor(other, 'blocked_prop')"); |
+ ExpectFalse("propertyIsEnumerable.call(other, 'blocked_prop')"); |
- value = CompileRun( |
+ // Enable ACCESS_HAS |
+ allowed_access_type[v8::ACCESS_HAS] = true; |
+ ExpectUndefined("other.blocked_prop"); |
+ // ... and now we can get the descriptor... |
+ ExpectUndefined( |
"Object.getOwnPropertyDescriptor(other, 'blocked_prop').value"); |
- CHECK(value->IsUndefined()); |
+ // ... and enumerate the property. |
+ ExpectTrue("propertyIsEnumerable.call(other, 'blocked_prop')"); |
+ allowed_access_type[v8::ACCESS_HAS] = false; |
- value = CompileRun("propertyIsEnumerable.call(other, 'blocked_prop')"); |
- CHECK(value->IsFalse()); |
+ // Access blocked element. |
+ CompileRun("other[239] = 1"); |
+ ExpectUndefined("other[239]"); |
+ ExpectUndefined("Object.getOwnPropertyDescriptor(other, '239')"); |
+ ExpectFalse("propertyIsEnumerable.call(other, '239')"); |
+ |
+ // Enable ACCESS_HAS |
+ allowed_access_type[v8::ACCESS_HAS] = true; |
+ ExpectUndefined("other[239]"); |
+ // ... and now we can get the descriptor... |
+ ExpectUndefined("Object.getOwnPropertyDescriptor(other, '239').value"); |
+ // ... and enumerate the property. |
+ ExpectTrue("propertyIsEnumerable.call(other, '239')"); |
+ allowed_access_type[v8::ACCESS_HAS] = false; |
+ |
+ // Access a property with JS accessor. |
+ CompileRun("other.js_accessor_p = 2"); |
+ |
+ ExpectUndefined("other.js_accessor_p"); |
+ ExpectUndefined( |
+ "Object.getOwnPropertyDescriptor(other, 'js_accessor_p')"); |
+ |
+ // Enable ACCESS_HAS. |
+ allowed_access_type[v8::ACCESS_HAS] = true; |
+ ExpectUndefined("other.js_accessor_p"); |
+ ExpectUndefined( |
+ "Object.getOwnPropertyDescriptor(other, 'js_accessor_p').get"); |
+ ExpectUndefined( |
+ "Object.getOwnPropertyDescriptor(other, 'js_accessor_p').set"); |
+ ExpectUndefined( |
+ "Object.getOwnPropertyDescriptor(other, 'js_accessor_p').value"); |
+ allowed_access_type[v8::ACCESS_HAS] = false; |
+ |
+ // Enable both ACCESS_HAS and ACCESS_GET. |
+ allowed_access_type[v8::ACCESS_HAS] = true; |
+ allowed_access_type[v8::ACCESS_GET] = true; |
+ |
+ ExpectString("other.js_accessor_p", "getter"); |
+ ExpectObject( |
+ "Object.getOwnPropertyDescriptor(other, 'js_accessor_p').get", getter); |
+ ExpectUndefined( |
+ "Object.getOwnPropertyDescriptor(other, 'js_accessor_p').set"); |
+ ExpectUndefined( |
+ "Object.getOwnPropertyDescriptor(other, 'js_accessor_p').value"); |
+ |
+ allowed_access_type[v8::ACCESS_GET] = false; |
+ allowed_access_type[v8::ACCESS_HAS] = false; |
+ |
+ // Enable both ACCESS_HAS and ACCESS_SET. |
+ allowed_access_type[v8::ACCESS_HAS] = true; |
+ allowed_access_type[v8::ACCESS_SET] = true; |
+ |
+ ExpectUndefined("other.js_accessor_p"); |
+ ExpectUndefined( |
+ "Object.getOwnPropertyDescriptor(other, 'js_accessor_p').get"); |
+ ExpectObject( |
+ "Object.getOwnPropertyDescriptor(other, 'js_accessor_p').set", setter); |
+ ExpectUndefined( |
+ "Object.getOwnPropertyDescriptor(other, 'js_accessor_p').value"); |
+ |
+ allowed_access_type[v8::ACCESS_SET] = false; |
+ allowed_access_type[v8::ACCESS_HAS] = false; |
+ |
+ // Enable both ACCESS_HAS, ACCESS_GET and ACCESS_SET. |
+ allowed_access_type[v8::ACCESS_HAS] = true; |
+ allowed_access_type[v8::ACCESS_GET] = true; |
+ allowed_access_type[v8::ACCESS_SET] = true; |
+ |
+ ExpectString("other.js_accessor_p", "getter"); |
+ ExpectObject( |
+ "Object.getOwnPropertyDescriptor(other, 'js_accessor_p').get", getter); |
+ ExpectObject( |
+ "Object.getOwnPropertyDescriptor(other, 'js_accessor_p').set", setter); |
+ ExpectUndefined( |
+ "Object.getOwnPropertyDescriptor(other, 'js_accessor_p').value"); |
+ |
+ allowed_access_type[v8::ACCESS_SET] = false; |
+ allowed_access_type[v8::ACCESS_GET] = false; |
+ allowed_access_type[v8::ACCESS_HAS] = false; |
+ |
+ // Access an element with JS accessor. |
+ CompileRun("other[42] = 2"); |
+ |
+ ExpectUndefined("other[42]"); |
+ ExpectUndefined("Object.getOwnPropertyDescriptor(other, '42')"); |
+ |
+ // Enable ACCESS_HAS. |
+ allowed_access_type[v8::ACCESS_HAS] = true; |
+ ExpectUndefined("other[42]"); |
+ ExpectUndefined("Object.getOwnPropertyDescriptor(other, '42').get"); |
+ ExpectUndefined("Object.getOwnPropertyDescriptor(other, '42').set"); |
+ ExpectUndefined("Object.getOwnPropertyDescriptor(other, '42').value"); |
+ allowed_access_type[v8::ACCESS_HAS] = false; |
+ |
+ // Enable both ACCESS_HAS and ACCESS_GET. |
+ allowed_access_type[v8::ACCESS_HAS] = true; |
+ allowed_access_type[v8::ACCESS_GET] = true; |
+ |
+ ExpectString("other[42]", "el_getter"); |
+ ExpectObject("Object.getOwnPropertyDescriptor(other, '42').get", el_getter); |
+ ExpectUndefined("Object.getOwnPropertyDescriptor(other, '42').set"); |
+ ExpectUndefined("Object.getOwnPropertyDescriptor(other, '42').value"); |
+ |
+ allowed_access_type[v8::ACCESS_GET] = false; |
+ allowed_access_type[v8::ACCESS_HAS] = false; |
+ |
+ // Enable both ACCESS_HAS and ACCESS_SET. |
+ allowed_access_type[v8::ACCESS_HAS] = true; |
+ allowed_access_type[v8::ACCESS_SET] = true; |
+ |
+ ExpectUndefined("other[42]"); |
+ ExpectUndefined("Object.getOwnPropertyDescriptor(other, '42').get"); |
+ ExpectObject("Object.getOwnPropertyDescriptor(other, '42').set", el_setter); |
+ ExpectUndefined("Object.getOwnPropertyDescriptor(other, '42').value"); |
+ |
+ allowed_access_type[v8::ACCESS_SET] = false; |
+ allowed_access_type[v8::ACCESS_HAS] = false; |
+ |
+ // Enable both ACCESS_HAS, ACCESS_GET and ACCESS_SET. |
+ allowed_access_type[v8::ACCESS_HAS] = true; |
+ allowed_access_type[v8::ACCESS_GET] = true; |
+ allowed_access_type[v8::ACCESS_SET] = true; |
+ |
+ ExpectString("other[42]", "el_getter"); |
+ ExpectObject("Object.getOwnPropertyDescriptor(other, '42').get", el_getter); |
+ ExpectObject("Object.getOwnPropertyDescriptor(other, '42').set", el_setter); |
+ ExpectUndefined("Object.getOwnPropertyDescriptor(other, '42').value"); |
+ |
+ allowed_access_type[v8::ACCESS_SET] = false; |
+ allowed_access_type[v8::ACCESS_GET] = false; |
+ allowed_access_type[v8::ACCESS_HAS] = false; |
+ |
+ v8::Handle<Value> value; |
+ |
// Access accessible property |
value = CompileRun("other.accessible_prop = 3"); |
CHECK(value->IsNumber()); |