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( ...@@ -2227,39 +2227,52 @@ Persistent<Context> v8::Context::New(
LOG_API("Context::New"); LOG_API("Context::New");
ON_BAILOUT("v8::Context::New()", return Persistent<Context>()); ON_BAILOUT("v8::Context::New()", return Persistent<Context>());
// Make sure that the global_template has a constructor. v8::Handle<ObjectTemplate> proxy_template = global_template;
if (!global_template.IsEmpty()) { i::Handle<i::FunctionTemplateInfo> proxy_constructor;
i::Handle<i::FunctionTemplateInfo> constructor = i::Handle<i::FunctionTemplateInfo> global_constructor;
EnsureConstructor(Utils::OpenHandle(*global_template));
// Create a fresh template for global proxy object. if (!global_template.IsEmpty()) {
Local<ObjectTemplate> proxy_template = ObjectTemplate::New(); // Make sure that the global_template has a constructor.
global_constructor = EnsureConstructor(Utils::OpenHandle(*global_template));
i::Handle<i::FunctionTemplateInfo> proxy_constructor = // Create a fresh template for the global proxy object.
EnsureConstructor(Utils::OpenHandle(*proxy_template)); proxy_template = ObjectTemplate::New();
proxy_constructor = EnsureConstructor(Utils::OpenHandle(*proxy_template));
// Set the global template to be the prototype template // Set the global template to be the prototype template of global
// of global proxy template. // proxy template.
proxy_constructor->set_prototype_template( proxy_constructor->set_prototype_template(
*Utils::OpenHandle(*global_template)); *Utils::OpenHandle(*global_template));
// Migrate security handlers from global_template to proxy_template. // Migrate security handlers from global_template to
if (!constructor->access_check_info()->IsUndefined()) { // proxy_template. Temporarily removing access check information
proxy_constructor->set_access_check_info( // from the global template.
constructor->access_check_info()); if (!global_constructor->access_check_info()->IsUndefined()) {
proxy_constructor->set_needs_access_check(true); proxy_constructor->set_access_check_info(
global_constructor->access_check_info());
// Remove access check info from global_template. proxy_constructor->set_needs_access_check(
constructor->set_needs_access_check(false); global_constructor->needs_access_check());
constructor->set_access_check_info(i::Heap::undefined_value()); 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( i::Handle<i::Context> env = i::Bootstrapper::CreateEnvironment(
Utils::OpenHandle(*global_object), 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(), if (!ApiCheck(!env.is_null(),
"v8::Context::New()", "v8::Context::New()",
"Could not initialize environment")) "Could not initialize environment"))
......
...@@ -5447,6 +5447,24 @@ THREADED_TEST(DisableAccessChecksWhileConfiguring) { ...@@ -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, static String::ExternalStringResource* SymbolCallback(const char* chars,
size_t length) { size_t length) {
uint16_t* buffer = i::NewArray<uint16_t>(length + 1); 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