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:
mstarzinger@chromium.org 2014-03-20 18:14:33 +00:00
parent 2b722b663e
commit c27758bcc7
2 changed files with 53 additions and 0 deletions

View File

@ -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);

View File

@ -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);
}