Interceptors expect the receiver to always be an JSReceiver.
BUG=chromium:609134 R=verwaest@chromium.org Review-Url: https://codereview.chromium.org/1973513002 Cr-Commit-Position: refs/heads/master@{#36203}
This commit is contained in:
parent
bafa239da0
commit
9c9708ac91
18
src/ic/ic.cc
18
src/ic/ic.cc
@ -2615,12 +2615,17 @@ RUNTIME_FUNCTION(Runtime_LoadPropertyWithInterceptorOnly) {
|
||||
DCHECK(args.length() == NamedLoadHandlerCompiler::kInterceptorArgsLength);
|
||||
Handle<Name> name =
|
||||
args.at<Name>(NamedLoadHandlerCompiler::kInterceptorArgsNameIndex);
|
||||
Handle<JSObject> receiver =
|
||||
args.at<JSObject>(NamedLoadHandlerCompiler::kInterceptorArgsThisIndex);
|
||||
Handle<Object> receiver =
|
||||
args.at<Object>(NamedLoadHandlerCompiler::kInterceptorArgsThisIndex);
|
||||
Handle<JSObject> holder =
|
||||
args.at<JSObject>(NamedLoadHandlerCompiler::kInterceptorArgsHolderIndex);
|
||||
HandleScope scope(isolate);
|
||||
|
||||
if (!receiver->IsJSReceiver()) {
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
|
||||
isolate, receiver, Object::ConvertReceiver(isolate, receiver));
|
||||
}
|
||||
|
||||
InterceptorInfo* interceptor = holder->GetNamedInterceptor();
|
||||
PropertyCallbackArguments arguments(isolate, interceptor->data(), *receiver,
|
||||
*holder, Object::DONT_THROW);
|
||||
@ -2646,11 +2651,16 @@ RUNTIME_FUNCTION(Runtime_LoadPropertyWithInterceptor) {
|
||||
DCHECK(args.length() == NamedLoadHandlerCompiler::kInterceptorArgsLength);
|
||||
Handle<Name> name =
|
||||
args.at<Name>(NamedLoadHandlerCompiler::kInterceptorArgsNameIndex);
|
||||
Handle<JSObject> receiver =
|
||||
args.at<JSObject>(NamedLoadHandlerCompiler::kInterceptorArgsThisIndex);
|
||||
Handle<Object> receiver =
|
||||
args.at<Object>(NamedLoadHandlerCompiler::kInterceptorArgsThisIndex);
|
||||
Handle<JSObject> holder =
|
||||
args.at<JSObject>(NamedLoadHandlerCompiler::kInterceptorArgsHolderIndex);
|
||||
|
||||
if (!receiver->IsJSReceiver()) {
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
|
||||
isolate, receiver, Object::ConvertReceiver(isolate, receiver));
|
||||
}
|
||||
|
||||
InterceptorInfo* interceptor = holder->GetNamedInterceptor();
|
||||
PropertyCallbackArguments arguments(isolate, interceptor->data(), *receiver,
|
||||
*holder, Object::DONT_THROW);
|
||||
|
@ -4109,8 +4109,14 @@ Maybe<bool> JSObject::SetPropertyWithInterceptor(LookupIterator* it,
|
||||
|
||||
Handle<JSObject> holder = it->GetHolder<JSObject>();
|
||||
bool result;
|
||||
PropertyCallbackArguments args(isolate, interceptor->data(),
|
||||
*it->GetReceiver(), *holder, should_throw);
|
||||
Handle<Object> receiver = it->GetReceiver();
|
||||
if (!receiver->IsJSReceiver()) {
|
||||
ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, receiver,
|
||||
Object::ConvertReceiver(isolate, receiver),
|
||||
Nothing<bool>());
|
||||
}
|
||||
PropertyCallbackArguments args(isolate, interceptor->data(), *receiver,
|
||||
*holder, should_throw);
|
||||
|
||||
if (it->IsElement()) {
|
||||
uint32_t index = it->index();
|
||||
@ -5394,9 +5400,14 @@ Maybe<PropertyAttributes> JSObject::GetPropertyAttributesWithInterceptor(
|
||||
!interceptor->can_intercept_symbols()) {
|
||||
return Just(ABSENT);
|
||||
}
|
||||
PropertyCallbackArguments args(isolate, interceptor->data(),
|
||||
*it->GetReceiver(), *holder,
|
||||
Object::DONT_THROW);
|
||||
Handle<Object> receiver = it->GetReceiver();
|
||||
if (!receiver->IsJSReceiver()) {
|
||||
ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, receiver,
|
||||
Object::ConvertReceiver(isolate, receiver),
|
||||
Nothing<PropertyAttributes>());
|
||||
}
|
||||
PropertyCallbackArguments args(isolate, interceptor->data(), *receiver,
|
||||
*holder, Object::DONT_THROW);
|
||||
if (!interceptor->query()->IsUndefined()) {
|
||||
Handle<Object> result;
|
||||
if (it->IsElement()) {
|
||||
@ -5840,9 +5851,15 @@ Maybe<bool> JSObject::DeletePropertyWithInterceptor(LookupIterator* it,
|
||||
if (interceptor->deleter()->IsUndefined()) return Nothing<bool>();
|
||||
|
||||
Handle<JSObject> holder = it->GetHolder<JSObject>();
|
||||
Handle<Object> receiver = it->GetReceiver();
|
||||
if (!receiver->IsJSReceiver()) {
|
||||
ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, receiver,
|
||||
Object::ConvertReceiver(isolate, receiver),
|
||||
Nothing<bool>());
|
||||
}
|
||||
|
||||
PropertyCallbackArguments args(isolate, interceptor->data(),
|
||||
*it->GetReceiver(), *holder, should_throw);
|
||||
PropertyCallbackArguments args(isolate, interceptor->data(), *receiver,
|
||||
*holder, should_throw);
|
||||
Handle<Object> result;
|
||||
if (it->IsElement()) {
|
||||
uint32_t index = it->index();
|
||||
@ -14949,9 +14966,13 @@ MaybeHandle<Object> JSObject::GetPropertyWithInterceptor(LookupIterator* it,
|
||||
|
||||
Handle<JSObject> holder = it->GetHolder<JSObject>();
|
||||
Handle<Object> result;
|
||||
PropertyCallbackArguments args(isolate, interceptor->data(),
|
||||
*it->GetReceiver(), *holder,
|
||||
Object::DONT_THROW);
|
||||
Handle<Object> receiver = it->GetReceiver();
|
||||
if (!receiver->IsJSReceiver()) {
|
||||
ASSIGN_RETURN_ON_EXCEPTION(
|
||||
isolate, receiver, Object::ConvertReceiver(isolate, receiver), Object);
|
||||
}
|
||||
PropertyCallbackArguments args(isolate, interceptor->data(), *receiver,
|
||||
*holder, Object::DONT_THROW);
|
||||
|
||||
if (it->IsElement()) {
|
||||
uint32_t index = it->index();
|
||||
|
@ -775,19 +775,18 @@ TEST(PrototypeGetterAccessCheck) {
|
||||
}
|
||||
}
|
||||
|
||||
static void check_receiver(Local<String> name,
|
||||
const v8::PropertyCallbackInfo<v8::Value>& info) {
|
||||
static void CheckReceiver(Local<String> name,
|
||||
const v8::PropertyCallbackInfo<v8::Value>& info) {
|
||||
CHECK(info.This()->IsObject());
|
||||
}
|
||||
|
||||
TEST(Regress609134) {
|
||||
v8::internal::FLAG_allow_natives_syntax = true;
|
||||
LocalContext env;
|
||||
v8::Isolate* isolate = env->GetIsolate();
|
||||
v8::HandleScope scope(isolate);
|
||||
auto fun_templ = v8::FunctionTemplate::New(isolate);
|
||||
fun_templ->InstanceTemplate()->SetNativeDataProperty(v8_str("foo"),
|
||||
check_receiver);
|
||||
CheckReceiver);
|
||||
|
||||
CHECK(env->Global()
|
||||
->Set(env.local(), v8_str("Fun"),
|
||||
|
@ -3888,3 +3888,28 @@ THREADED_TEST(NonMaskingInterceptorGlobalEvalRegression) {
|
||||
"eval('obj.x');",
|
||||
9);
|
||||
}
|
||||
|
||||
static void CheckReceiver(Local<Name> name,
|
||||
const v8::PropertyCallbackInfo<v8::Value>& info) {
|
||||
CHECK(info.This()->IsObject());
|
||||
}
|
||||
|
||||
TEST(Regress609134Interceptor) {
|
||||
LocalContext env;
|
||||
v8::Isolate* isolate = env->GetIsolate();
|
||||
v8::HandleScope scope(isolate);
|
||||
auto fun_templ = v8::FunctionTemplate::New(isolate);
|
||||
fun_templ->InstanceTemplate()->SetHandler(
|
||||
v8::NamedPropertyHandlerConfiguration(CheckReceiver));
|
||||
|
||||
CHECK(env->Global()
|
||||
->Set(env.local(), v8_str("Fun"),
|
||||
fun_templ->GetFunction(env.local()).ToLocalChecked())
|
||||
.FromJust());
|
||||
|
||||
CompileRun(
|
||||
"var f = new Fun();"
|
||||
"Number.prototype.__proto__ = f;"
|
||||
"var a = 42;"
|
||||
"for (var i = 0; i<3; i++) { a.foo; }");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user