summaryrefslogtreecommitdiff
path: root/Userland/Libraries
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 /Userland/Libraries
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.
Diffstat (limited to 'Userland/Libraries')
-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");
+});