summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2021-06-19 11:34:19 +0200
committerAndreas Kling <kling@serenityos.org>2021-06-19 11:34:19 +0200
commit686213c2b81f408addca928ef1508e2af0354f9c (patch)
tree13fd399302c071634fda5e8f8559005c0f99e8e0
parent25baefdd1e7c8efefd4ddf5cb2af363b4e9ebd22 (diff)
downloadserenity-686213c2b81f408addca928ef1508e2af0354f9c.zip
LibJS: Make Object.getOwnPropertyDescriptor() work on String subscripts
String objects are a bit special since the indexed properties are overridden by the contents of the underlying PrimitiveString. getOwnPropertyDescriptor() was not taking this into account, and would instead return undefined when asked about an indexed property in a String object.
-rw-r--r--Userland/Libraries/LibJS/Runtime/StringObject.cpp14
-rw-r--r--Userland/Libraries/LibJS/Runtime/StringObject.h1
-rw-r--r--Userland/Libraries/LibJS/Tests/builtins/Object/Object.getOwnPropertyDescriptor.js9
3 files changed, 24 insertions, 0 deletions
diff --git a/Userland/Libraries/LibJS/Runtime/StringObject.cpp b/Userland/Libraries/LibJS/Runtime/StringObject.cpp
index d73d8bad43..b23015ef12 100644
--- a/Userland/Libraries/LibJS/Runtime/StringObject.cpp
+++ b/Userland/Libraries/LibJS/Runtime/StringObject.cpp
@@ -39,4 +39,18 @@ void StringObject::visit_edges(Cell::Visitor& visitor)
visitor.visit(&m_string);
}
+Optional<PropertyDescriptor> StringObject::get_own_property_descriptor(PropertyName const& property_name) const
+{
+ if (!property_name.is_number() || property_name.as_number() >= m_string.string().length())
+ return Base::get_own_property_descriptor(property_name);
+
+ PropertyDescriptor descriptor;
+ descriptor.value = js_string(heap(), m_string.string().substring(property_name.as_number(), 1));
+ descriptor.attributes.set_has_configurable();
+ descriptor.attributes.set_has_enumerable();
+ descriptor.attributes.set_has_writable();
+ descriptor.attributes.set_enumerable();
+ return descriptor;
+}
+
}
diff --git a/Userland/Libraries/LibJS/Runtime/StringObject.h b/Userland/Libraries/LibJS/Runtime/StringObject.h
index 8c7ee5cc94..3f74ec8769 100644
--- a/Userland/Libraries/LibJS/Runtime/StringObject.h
+++ b/Userland/Libraries/LibJS/Runtime/StringObject.h
@@ -29,6 +29,7 @@ public:
private:
virtual bool is_string_object() const final { return true; }
virtual void visit_edges(Visitor&) override;
+ virtual Optional<PropertyDescriptor> get_own_property_descriptor(PropertyName const&) const override;
PrimitiveString& m_string;
};
diff --git a/Userland/Libraries/LibJS/Tests/builtins/Object/Object.getOwnPropertyDescriptor.js b/Userland/Libraries/LibJS/Tests/builtins/Object/Object.getOwnPropertyDescriptor.js
index ee1fcef2fb..ec12161d33 100644
--- a/Userland/Libraries/LibJS/Tests/builtins/Object/Object.getOwnPropertyDescriptor.js
+++ b/Userland/Libraries/LibJS/Tests/builtins/Object/Object.getOwnPropertyDescriptor.js
@@ -86,3 +86,12 @@ test("defined property", () => {
expect(o).not.toHaveGetterProperty(1);
expect(o).not.toHaveSetterProperty(1);
});
+
+test("String object indexed properties", () => {
+ expect("foo").toHaveValueProperty(0, "f");
+ expect("foo").toHaveEnumerableProperty(0);
+ expect("foo").not.toHaveConfigurableProperty(0);
+ expect("foo").not.toHaveWritableProperty(0);
+
+ expect("foo").toHaveValueProperty(1, "o");
+});