1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-26 09:07:35 +00:00

LibJS: Append first sparse element to packed elements in take_first()

Otherwise we continuously lose the first sparse element (at index
SPARSE_ARRAY_THRESHOLD) without noticing, as we overwrite all indices
with the value at index+1.

Fixes #5884.
This commit is contained in:
Linus Groh 2021-03-20 13:43:42 +01:00 committed by Andreas Kling
parent 611b3c2c49
commit ae95ed5ddd
2 changed files with 20 additions and 3 deletions

View file

@ -180,14 +180,19 @@ ValueAndAttributes GenericIndexedPropertyStorage::take_first()
VERIFY(m_array_size > 0); VERIFY(m_array_size > 0);
m_array_size--; m_array_size--;
auto first_element = m_packed_elements.take_first();
if (!m_sparse_elements.is_empty()) { if (!m_sparse_elements.is_empty()) {
m_packed_elements.append(m_sparse_elements.get(SPARSE_ARRAY_THRESHOLD).value_or({}));
HashMap<u32, ValueAndAttributes> new_sparse_elements; HashMap<u32, ValueAndAttributes> new_sparse_elements;
for (auto& entry : m_sparse_elements) for (auto& entry : m_sparse_elements) {
new_sparse_elements.set(entry.key - 1, entry.value); if (entry.key - 1 >= SPARSE_ARRAY_THRESHOLD)
new_sparse_elements.set(entry.key - 1, entry.value);
}
m_sparse_elements = move(new_sparse_elements); m_sparse_elements = move(new_sparse_elements);
} }
return m_packed_elements.take_first(); return first_element;
} }
ValueAndAttributes GenericIndexedPropertyStorage::take_last() ValueAndAttributes GenericIndexedPropertyStorage::take_last()

View file

@ -21,3 +21,15 @@ describe("normal behavior", () => {
expect(a).toEqual([]); expect(a).toEqual([]);
}); });
}); });
test("Issue #5884, GenericIndexedPropertyStorage::take_first() loses elements", () => {
const a = [];
for (let i = 0; i < 300; i++) {
a.push(i);
}
expect(a.length).toBe(300);
for (let i = 0; i < 300; i++) {
a.shift();
}
expect(a.length).toBe(0);
});