LibWeb: Track deleted state on IndexedDb Index and ObjectStore

An `InvalidStateError` is now thrown when an attempt is made to
interact with an index or object store that has been deleted.
This commit is contained in:
Tim Ledbetter
2026-02-24 13:34:41 +00:00
committed by Jelle Raaijmakers
parent f06732d180
commit 84043cd82d
Notes: github-actions[bot] 2026-02-24 16:38:11 +00:00
14 changed files with 310 additions and 51 deletions

View File

@@ -82,6 +82,17 @@ void IDBCursorWithValue::visit_edges(Visitor& visitor)
Base::visit_edges(visitor);
}
bool IDBCursor::is_source_or_object_store_deleted() const
{
return m_source_handle.visit(
[](GC::Ref<IDBObjectStore> object_store) {
return object_store->store()->is_deleted();
},
[](GC::Ref<IDBIndex> index) {
return index->index()->is_deleted() || index->index()->object_store()->is_deleted();
});
}
// https://w3c.github.io/IndexedDB/#cursor-transaction
GC::Ref<IDBTransaction> IDBCursor::transaction()
{
@@ -122,7 +133,9 @@ WebIDL::ExceptionOr<void> IDBCursor::continue_(JS::Value key)
if (!transaction->is_active())
return WebIDL::TransactionInactiveError::create(realm, "Transaction is not active while continuing cursor"_utf16);
// FIXME: 3. If this's source or effective object store has been deleted, throw an "InvalidStateError" DOMException
// 3. If thiss source or effective object store has been deleted, throw an "InvalidStateError" DOMException.
if (is_source_or_object_store_deleted())
return WebIDL::InvalidStateError::create(realm, "Source or its object store has been deleted"_utf16);
// 4. If this's got value flag is false, indicating that the cursor is being iterated or has iterated past its end, throw an "InvalidStateError" DOMException.
if (!m_got_value)
@@ -213,7 +226,9 @@ WebIDL::ExceptionOr<void> IDBCursor::advance(WebIDL::UnsignedLong count)
if (!transaction->is_active())
return WebIDL::TransactionInactiveError::create(realm, "Transaction is not active while advancing cursor"_utf16);
// FIXME: 4. If thiss source or effective object store has been deleted, throw an "InvalidStateError" DOMException.
// 4. If thiss source or effective object store has been deleted, throw an "InvalidStateError" DOMException.
if (is_source_or_object_store_deleted())
return WebIDL::InvalidStateError::create(realm, "Source or its object store has been deleted"_utf16);
// 5. If thiss got value flag is false, indicating that the cursor is being iterated or has iterated past its end, throw an "InvalidStateError" DOMException.
if (!m_got_value)
@@ -255,7 +270,9 @@ WebIDL::ExceptionOr<void> IDBCursor::continue_primary_key(JS::Value key_param, J
if (!transaction->is_active())
return WebIDL::TransactionInactiveError::create(realm, "Transaction is not active while continuing cursor"_utf16);
// FIXME: 3. If thiss source or effective object store has been deleted, throw an "InvalidStateError" DOMException.
// 3. If thiss source or effective object store has been deleted, throw an "InvalidStateError" DOMException.
if (is_source_or_object_store_deleted())
return WebIDL::InvalidStateError::create(realm, "Source or its object store has been deleted"_utf16);
// 4. If thiss source is not an index throw an "InvalidAccessError" DOMException.
if (!m_source_handle.has<GC::Ref<IDBIndex>>())
@@ -359,7 +376,9 @@ WebIDL::ExceptionOr<GC::Ref<IDBRequest>> IDBCursor::update(JS::Value value)
if (transaction->is_readonly())
return WebIDL::ReadOnlyError::create(realm, "Transaction is read-only while updating cursor"_utf16);
// FIXME: 4. If thiss source or effective object store has been deleted, throw an "InvalidStateError" DOMException.
// 4. If thiss source or effective object store has been deleted, throw an "InvalidStateError" DOMException.
if (is_source_or_object_store_deleted())
return WebIDL::InvalidStateError::create(realm, "Source or its object store has been deleted"_utf16);
// 5. If thiss got value flag is false, indicating that the cursor is being iterated or has iterated past its end, throw an "InvalidStateError" DOMException.
if (!m_got_value)
@@ -426,7 +445,9 @@ WebIDL::ExceptionOr<GC::Ref<IDBRequest>> IDBCursor::delete_()
if (transaction->is_readonly())
return WebIDL::ReadOnlyError::create(realm, "Transaction is read-only while deleting cursor"_utf16);
// FIXME: 4. If thiss source or effective object store has been deleted, throw an "InvalidStateError" DOMException.
// 4. If thiss source or effective object store has been deleted, throw an "InvalidStateError" DOMException.
if (is_source_or_object_store_deleted())
return WebIDL::InvalidStateError::create(realm, "Source or its object store has been deleted"_utf16);
// 5. If thiss got value flag is false, indicating that the cursor is being iterated or has iterated past its end, throw an "InvalidStateError" DOMException.
if (!m_got_value)