Handle<FixedArray> GetKeysInFixedArrayFor(Handle<JSObject> object) {
Handle<FixedArray> content = Factory::empty_fixed_array();
- // Check access rights if required.
- if (object->IsAccessCheckNeeded() &&
- !Top::MayNamedAccess(*object, Heap::undefined_value(), v8::ACCESS_KEYS)) {
- Top::ReportFailedAccessCheck(*object, v8::ACCESS_KEYS);
- return content;
- }
-
JSObject* arguments_boilerplate =
Top::context()->global_context()->arguments_boilerplate();
JSFunction* arguments_function =
p = Handle<Object>(p->GetPrototype())) {
Handle<JSObject> current(JSObject::cast(*p));
+ // Check access rights if required.
+ if (current->IsAccessCheckNeeded() &&
+ !Top::MayNamedAccess(*current, Heap::undefined_value(),
+ v8::ACCESS_KEYS)) {
+ Top::ReportFailedAccessCheck(*current, v8::ACCESS_KEYS);
+ break;
+ }
+
// Compute the property keys.
content = UnionOfKeys(content, GetEnumPropertyKeys(current));
}
+THREADED_TEST(CrossDomainForIn) {
+ v8::HandleScope handle_scope;
+ LocalContext env1;
+ v8::Persistent<Context> env2 = Context::New();
+
+ Local<Value> foo = v8_str("foo");
+ Local<Value> bar = v8_str("bar");
+
+ // Set to the same domain.
+ env1->SetSecurityToken(foo);
+ env2->SetSecurityToken(foo);
+
+ env1->Global()->Set(v8_str("prop"), v8_num(3));
+ env2->Global()->Set(v8_str("env1"), env1->Global());
+
+ // Change env2 to a different domain and set env1's global object
+ // as the __proto__ of an object in env2 and enumerate properties
+ // in for-in. It shouldn't enumerate properties on env1's global
+ // object.
+ env2->SetSecurityToken(bar);
+ {
+ Context::Scope scope_env2(env2);
+ Local<Value> result =
+ CompileRun("(function(){var obj = {'__proto__':env1};"
+ "for (var p in obj)"
+ " if (p == 'prop') return false;"
+ "return true;})()");
+ CHECK(result->IsTrue());
+ }
+ env2.Dispose();
+}
+
static bool NamedAccessBlocker(Local<v8::Object> global,
Local<Value> name,