From 19f505d32012928edc27856345f068e5122e3e5b Mon Sep 17 00:00:00 2001 From: davidot Date: Fri, 25 Jun 2021 17:01:00 +0200 Subject: [PATCH] LibJS: Fix propagation of setters and getters from prototypes If we define a property with just a setter/getter (not both) we must: - take the previous getter/setter if defined on the actual object - overwrite the other to nullptr if it is from a prototype --- Userland/Libraries/LibJS/Runtime/Object.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Userland/Libraries/LibJS/Runtime/Object.cpp b/Userland/Libraries/LibJS/Runtime/Object.cpp index c386e93771d..7bc5a569527 100644 --- a/Userland/Libraries/LibJS/Runtime/Object.cpp +++ b/Userland/Libraries/LibJS/Runtime/Object.cpp @@ -438,11 +438,13 @@ Value Object::get_own_property_descriptor_object(const PropertyName& property_na if (descriptor.is_data_descriptor()) { descriptor_object->define_property(vm.names.value, descriptor.value.value_or(js_undefined())); descriptor_object->define_property(vm.names.writable, Value(descriptor.attributes.is_writable())); - } else { - VERIFY(descriptor.is_accessor_descriptor()); + } + + if (descriptor.is_accessor_descriptor()) { descriptor_object->define_property(vm.names.get, descriptor.getter ? Value(descriptor.getter) : js_undefined()); descriptor_object->define_property(vm.names.set, descriptor.setter ? Value(descriptor.setter) : js_undefined()); } + descriptor_object->define_property(vm.names.enumerable, Value(descriptor.attributes.is_enumerable())); descriptor_object->define_property(vm.names.configurable, Value(descriptor.attributes.is_configurable())); return descriptor_object; @@ -491,7 +493,8 @@ bool Object::define_property(const StringOrSymbol& property_name, const Object& Function* getter_function { nullptr }; Function* setter_function { nullptr }; - auto existing_property = get_without_side_effects(property_name).value_or(js_undefined()); + // We should only take previous getters for our own object not from any prototype + auto existing_property = get_own_property(property_name, {}, AllowSideEffects::No).value_or(js_undefined()); if (getter.is_function()) { getter_function = &getter.as_function();