Commit e06ace6b authored by Anna Henningsen's avatar Anna Henningsen Committed by Commit Bot

[api] Fix empty Maybe crash in GetRealNamedPropertyAttributes

`Object::GetRealNamedPropertyAttributes()` can crash if an empty
`Maybe` is returned by `JSReceiver::GetPropertyAttributes()` because
it was not checking for that. Fix that.

Refs: https://github.com/nodejs/node/issues/34606
Change-Id: Ic83f904ba7134786bcd8f786eb2ce98adb4fea1e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2335057
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: 's avatarLeszek Swirski <leszeks@chromium.org>
Cr-Commit-Position: refs/heads/master@{#69258}
parent 6315167f
......@@ -4728,9 +4728,9 @@ Maybe<PropertyAttribute>
v8::Object::GetRealNamedPropertyAttributesInPrototypeChain(
Local<Context> context, Local<Name> key) {
auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
ENTER_V8_NO_SCRIPT(isolate, context, Object,
GetRealNamedPropertyAttributesInPrototypeChain,
Nothing<PropertyAttribute>(), i::HandleScope);
ENTER_V8(isolate, context, Object,
GetRealNamedPropertyAttributesInPrototypeChain,
Nothing<PropertyAttribute>(), i::HandleScope);
i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
if (!self->IsJSObject()) return Nothing<PropertyAttribute>();
i::Handle<i::Name> key_obj = Utils::OpenHandle(*key);
......@@ -4743,6 +4743,7 @@ v8::Object::GetRealNamedPropertyAttributesInPrototypeChain(
i::LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
Maybe<i::PropertyAttributes> result =
i::JSReceiver::GetPropertyAttributes(&it);
has_pending_exception = result.IsNothing();
RETURN_ON_FAILED_EXECUTION_PRIMITIVE(PropertyAttribute);
if (!it.IsFound()) return Nothing<PropertyAttribute>();
if (result.FromJust() == i::ABSENT) return Just(None);
......@@ -4767,14 +4768,15 @@ MaybeLocal<Value> v8::Object::GetRealNamedProperty(Local<Context> context,
Maybe<PropertyAttribute> v8::Object::GetRealNamedPropertyAttributes(
Local<Context> context, Local<Name> key) {
auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
ENTER_V8_NO_SCRIPT(isolate, context, Object, GetRealNamedPropertyAttributes,
Nothing<PropertyAttribute>(), i::HandleScope);
ENTER_V8(isolate, context, Object, GetRealNamedPropertyAttributes,
Nothing<PropertyAttribute>(), i::HandleScope);
i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
i::Handle<i::Name> key_obj = Utils::OpenHandle(*key);
i::LookupIterator::Key lookup_key(isolate, key_obj);
i::LookupIterator it(isolate, self, lookup_key, self,
i::LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
auto result = i::JSReceiver::GetPropertyAttributes(&it);
has_pending_exception = result.IsNothing();
RETURN_ON_FAILED_EXECUTION_PRIMITIVE(PropertyAttribute);
if (!it.IsFound()) return Nothing<PropertyAttribute>();
if (result.FromJust() == i::ABSENT) {
......
......@@ -11985,6 +11985,48 @@ THREADED_TEST(VariousGetPropertiesAndThrowingCallbacks) {
CHECK(result.IsEmpty());
}
THREADED_TEST(GetRealNamedPropertyAttributes_With_Proxy) {
LocalContext context;
HandleScope scope(context->GetIsolate());
{
Local<Object> proxy =
CompileRun(
"new Proxy({ p: 1 }, { getOwnPropertyDescriptor: _ => { "
" throw new Error('xyz'); } });")
.As<Object>();
TryCatch try_catch(context->GetIsolate());
v8::Maybe<v8::PropertyAttribute> result =
proxy->GetRealNamedPropertyAttributes(context.local(), v8_str("p"));
CHECK(result.IsNothing());
CHECK(try_catch.HasCaught());
CHECK(try_catch.Exception()
.As<Object>()
->Get(context.local(), v8_str("message"))
.ToLocalChecked()
->StrictEquals(v8_str("xyz")));
}
{
Local<Object> proxy =
CompileRun(
"Object.create("
" new Proxy({ p: 1 }, { getOwnPropertyDescriptor: _ => { "
" throw new Error('abc'); } }))")
.As<Object>();
TryCatch try_catch(context->GetIsolate());
v8::Maybe<v8::PropertyAttribute> result =
proxy->GetRealNamedPropertyAttributesInPrototypeChain(context.local(),
v8_str("p"));
CHECK(result.IsNothing());
CHECK(try_catch.HasCaught());
CHECK(try_catch.Exception()
.As<Object>()
->Get(context.local(), v8_str("message"))
.ToLocalChecked()
->StrictEquals(v8_str("abc")));
}
}
static void ThrowingCallbackWithTryCatch(
const v8::FunctionCallbackInfo<v8::Value>& args) {
......
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