Commit e8b56e6f authored by ager@chromium.org's avatar ager@chromium.org

Make sure that the API does not change templates pass in from the

user.  The API should never change templates behind the back of the
user.
Review URL: http://codereview.chromium.org/13741

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@963 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 2ea951c6
......@@ -2227,39 +2227,52 @@ Persistent<Context> v8::Context::New(
LOG_API("Context::New");
ON_BAILOUT("v8::Context::New()", return Persistent<Context>());
// Make sure that the global_template has a constructor.
if (!global_template.IsEmpty()) {
i::Handle<i::FunctionTemplateInfo> constructor =
EnsureConstructor(Utils::OpenHandle(*global_template));
v8::Handle<ObjectTemplate> proxy_template = global_template;
i::Handle<i::FunctionTemplateInfo> proxy_constructor;
i::Handle<i::FunctionTemplateInfo> global_constructor;
// Create a fresh template for global proxy object.
Local<ObjectTemplate> proxy_template = ObjectTemplate::New();
if (!global_template.IsEmpty()) {
// Make sure that the global_template has a constructor.
global_constructor = EnsureConstructor(Utils::OpenHandle(*global_template));
i::Handle<i::FunctionTemplateInfo> proxy_constructor =
EnsureConstructor(Utils::OpenHandle(*proxy_template));
// Create a fresh template for the global proxy object.
proxy_template = ObjectTemplate::New();
proxy_constructor = EnsureConstructor(Utils::OpenHandle(*proxy_template));
// Set the global template to be the prototype template
// of global proxy template.
// Set the global template to be the prototype template of global
// proxy template.
proxy_constructor->set_prototype_template(
*Utils::OpenHandle(*global_template));
// Migrate security handlers from global_template to proxy_template.
if (!constructor->access_check_info()->IsUndefined()) {
proxy_constructor->set_access_check_info(
constructor->access_check_info());
proxy_constructor->set_needs_access_check(true);
// Remove access check info from global_template.
constructor->set_needs_access_check(false);
constructor->set_access_check_info(i::Heap::undefined_value());
// Migrate security handlers from global_template to
// proxy_template. Temporarily removing access check information
// from the global template.
if (!global_constructor->access_check_info()->IsUndefined()) {
proxy_constructor->set_access_check_info(
global_constructor->access_check_info());
proxy_constructor->set_needs_access_check(
global_constructor->needs_access_check());
global_constructor->set_needs_access_check(false);
global_constructor->set_access_check_info(i::Heap::undefined_value());
}
global_template = proxy_template;
}
// Create the environment.
i::Handle<i::Context> env = i::Bootstrapper::CreateEnvironment(
Utils::OpenHandle(*global_object),
global_template, extensions);
proxy_template,
extensions);
// Restore the access check info on the global template.
if (!global_template.IsEmpty()) {
ASSERT(!global_constructor.is_null());
ASSERT(!proxy_constructor.is_null());
global_constructor->set_access_check_info(
proxy_constructor->access_check_info());
global_constructor->set_needs_access_check(
proxy_constructor->needs_access_check());
}
if (!ApiCheck(!env.is_null(),
"v8::Context::New()",
"Could not initialize environment"))
......
......@@ -5447,6 +5447,24 @@ THREADED_TEST(DisableAccessChecksWhileConfiguring) {
}
// This tests that access check information remains on the global
// object template when creating contexts.
THREADED_TEST(AccessControlRepeatedContextCreation) {
v8::HandleScope handle_scope;
v8::Handle<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New();
global_template->SetAccessCheckCallbacks(NamedSetAccessBlocker,
IndexedSetAccessBlocker);
i::Handle<i::ObjectTemplateInfo> internal_template =
v8::Utils::OpenHandle(*global_template);
CHECK(!internal_template->constructor()->IsUndefined());
i::Handle<i::FunctionTemplateInfo> constructor(
i::FunctionTemplateInfo::cast(internal_template->constructor()));
CHECK(!constructor->access_check_info()->IsUndefined());
v8::Persistent<Context> context0 = Context::New(NULL, global_template);
CHECK(!constructor->access_check_info()->IsUndefined());
}
static String::ExternalStringResource* SymbolCallback(const char* chars,
size_t length) {
uint16_t* buffer = i::NewArray<uint16_t>(length + 1);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment