From 5c8cb1689a543955cd1a47d3c323f8710b8b0f15 Mon Sep 17 00:00:00 2001 From: ishell Date: Mon, 25 Jul 2016 05:30:45 -0700 Subject: [PATCH] [ic] Don't call LookupIterator::GetStoreTarget() when receiver is not a JSReceiver. BUG=chromium:619166,chromium:625155 Review-Url: https://codereview.chromium.org/2175273002 Cr-Commit-Position: refs/heads/master@{#38018} --- src/lookup.h | 1 + src/objects.cc | 12 ++++++++---- test/cctest/test-api-interceptors.cc | 19 +++++++++++++++++++ 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/src/lookup.h b/src/lookup.h index a1e39599cc..ffc7904b2a 100644 --- a/src/lookup.h +++ b/src/lookup.h @@ -176,6 +176,7 @@ class LookupIterator final BASE_EMBEDDED { Handle GetReceiver() const { return receiver_; } Handle GetStoreTarget() const { + DCHECK(receiver_->IsJSObject()); if (receiver_->IsJSGlobalProxy()) { Map* map = JSGlobalProxy::cast(*receiver_)->map(); if (map->has_hidden_prototype()) { diff --git a/src/objects.cc b/src/objects.cc index 45bdb1dc9f..386cd98498 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -4374,15 +4374,18 @@ Maybe Object::SetPropertyInternal(LookupIterator* it, value, it->GetReceiver(), language_mode); case LookupIterator::INTERCEPTOR: { - Handle store_target_map = - handle(it->GetStoreTarget()->map(), it->isolate()); + Handle store_target_map; + if (it->GetReceiver()->IsJSObject()) { + store_target_map = handle(it->GetStoreTarget()->map(), it->isolate()); + } if (it->HolderIsReceiverOrHiddenPrototype()) { Maybe result = JSObject::SetPropertyWithInterceptor(it, should_throw, value); if (result.IsNothing() || result.FromJust()) return result; // Interceptor modified the store target but failed to set the // property. - Utils::ApiCheck(*store_target_map == it->GetStoreTarget()->map(), + Utils::ApiCheck(store_target_map.is_null() || + *store_target_map == it->GetStoreTarget()->map(), it->IsElement() ? "v8::IndexedPropertySetterCallback" : "v8::NamedPropertySetterCallback", "Interceptor silently changed store target."); @@ -4395,7 +4398,8 @@ Maybe Object::SetPropertyInternal(LookupIterator* it, } // Interceptor modified the store target but failed to set the // property. - Utils::ApiCheck(*store_target_map == it->GetStoreTarget()->map(), + Utils::ApiCheck(store_target_map.is_null() || + *store_target_map == it->GetStoreTarget()->map(), it->IsElement() ? "v8::IndexedPropertySetterCallback" : "v8::NamedPropertySetterCallback", "Interceptor silently changed store target."); diff --git a/test/cctest/test-api-interceptors.cc b/test/cctest/test-api-interceptors.cc index 1108c87859..3e2d8dc5be 100644 --- a/test/cctest/test-api-interceptors.cc +++ b/test/cctest/test-api-interceptors.cc @@ -3292,6 +3292,25 @@ THREADED_TEST(Regress149912) { CompileRun("Number.prototype.__proto__ = new Bug; var x = 0; x.foo();"); } +THREADED_TEST(Regress625155) { + LocalContext context; + v8::HandleScope scope(context->GetIsolate()); + Local templ = FunctionTemplate::New(context->GetIsolate()); + AddInterceptor(templ, EmptyInterceptorGetter, EmptyInterceptorSetter); + context->Global() + ->Set(context.local(), v8_str("Bug"), + templ->GetFunction(context.local()).ToLocalChecked()) + .FromJust(); + CompileRun( + "Number.prototype.__proto__ = new Bug;" + "var x;" + "x = 0xdead;" + "x.boom = 0;" + "x = 's';" + "x.boom = 0;" + "x = 1.5;" + "x.boom = 0;"); +} THREADED_TEST(Regress125988) { v8::HandleScope scope(CcTest::isolate());