LibJS: Don't remove non-configurable items in Array when setting length

This commit is contained in:
davidot 2021-06-25 16:55:38 +02:00 committed by Linus Groh
parent c7aaf40a35
commit b38fb418f8
Notes: sideshowbarker 2024-07-18 11:28:48 +09:00
2 changed files with 31 additions and 2 deletions

View file

@ -168,13 +168,32 @@ ValueAndAttributes GenericIndexedPropertyStorage::take_last()
void GenericIndexedPropertyStorage::set_array_like_size(size_t new_size)
{
m_array_size = new_size;
if (new_size == m_array_size)
return;
if (new_size >= m_array_size) {
m_array_size = new_size;
return;
}
size_t highest_index = 0;
bool any_left = false;
HashMap<u32, ValueAndAttributes> new_sparse_elements;
for (auto& entry : m_sparse_elements) {
if (entry.key < new_size)
if (entry.key < new_size || !entry.value.attributes.is_configurable()) {
new_sparse_elements.set(entry.key, entry.value);
any_left = true;
highest_index = max(highest_index, (size_t)entry.key);
}
}
if (any_left) {
m_array_size = max(highest_index + 1, new_size);
} else {
m_array_size = new_size;
}
m_sparse_elements = move(new_sparse_elements);
}

View file

@ -44,4 +44,14 @@ describe("normal behavior", () => {
b.length = 0x80000001;
expect(b.length).toEqual(0x80000001);
});
test("should not remove non-configurable values", () => {
var a = [1, undefined, 3];
Object.defineProperty(a, 1, { configurable: false, value: 2 });
expect(a.length).toEqual(3);
expect((a.length = 1)).toEqual(1);
expect(a.length).toEqual(2);
expect(a[1]).toEqual(2);
});
});