Fix missing access check in Runtime_SetPrototype.
R=rossberg@chromium.org BUG=chromium:354123 TEST=cctest/test-api/Regress354123 LOG=y Review URL: https://codereview.chromium.org/205033011 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@20138 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
2b722b663e
commit
c27758bcc7
@ -1686,6 +1686,14 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SetPrototype) {
|
||||
ASSERT(args.length() == 2);
|
||||
CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
|
||||
CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1);
|
||||
if (obj->IsAccessCheckNeeded() &&
|
||||
!isolate->MayNamedAccessWrapper(obj,
|
||||
isolate->factory()->proto_string(),
|
||||
v8::ACCESS_SET)) {
|
||||
isolate->ReportFailedAccessCheckWrapper(obj, v8::ACCESS_SET);
|
||||
RETURN_IF_SCHEDULED_EXCEPTION(isolate);
|
||||
return isolate->heap()->undefined_value();
|
||||
}
|
||||
if (obj->map()->is_observed()) {
|
||||
Handle<Object> old_value(
|
||||
GetPrototypeSkipHiddenPrototypes(isolate, *obj), isolate);
|
||||
|
@ -22298,3 +22298,48 @@ TEST(ThrowOnJavascriptExecution) {
|
||||
CompileRun("1+1");
|
||||
CHECK(try_catch.HasCaught());
|
||||
}
|
||||
|
||||
|
||||
TEST(Regress354123) {
|
||||
LocalContext current;
|
||||
v8::Isolate* isolate = current->GetIsolate();
|
||||
v8::HandleScope scope(isolate);
|
||||
|
||||
v8::Handle<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(isolate);
|
||||
templ->SetAccessCheckCallbacks(NamedAccessCounter, IndexedAccessCounter);
|
||||
current->Global()->Set(v8_str("friend"), templ->NewInstance());
|
||||
|
||||
// Test access using __proto__ from the prototype chain.
|
||||
named_access_count = 0;
|
||||
CompileRun("friend.__proto__ = {};");
|
||||
CHECK_EQ(2, named_access_count);
|
||||
CompileRun("friend.__proto__;");
|
||||
CHECK_EQ(4, named_access_count);
|
||||
|
||||
// Test access using __proto__ as a hijacked function (A).
|
||||
named_access_count = 0;
|
||||
CompileRun("var p = Object.prototype;"
|
||||
"var f = Object.getOwnPropertyDescriptor(p, '__proto__').set;"
|
||||
"f.call(friend, {});");
|
||||
CHECK_EQ(1, named_access_count);
|
||||
CompileRun("var p = Object.prototype;"
|
||||
"var f = Object.getOwnPropertyDescriptor(p, '__proto__').get;"
|
||||
"f.call(friend);");
|
||||
CHECK_EQ(2, named_access_count);
|
||||
|
||||
// Test access using __proto__ as a hijacked function (B).
|
||||
named_access_count = 0;
|
||||
CompileRun("var f = Object.prototype.__lookupSetter__('__proto__');"
|
||||
"f.call(friend, {});");
|
||||
CHECK_EQ(1, named_access_count);
|
||||
CompileRun("var f = Object.prototype.__lookupGetter__('__proto__');"
|
||||
"f.call(friend);");
|
||||
CHECK_EQ(2, named_access_count);
|
||||
|
||||
// Test access using Object.setPrototypeOf reflective method.
|
||||
named_access_count = 0;
|
||||
CompileRun("Object.setPrototypeOf(friend, {});");
|
||||
CHECK_EQ(1, named_access_count);
|
||||
CompileRun("Object.getPrototypeOf(friend);");
|
||||
CHECK_EQ(2, named_access_count);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user