LibWeb/IDB: Fix a bug where the KeyGenerator was not incremented

This commit is contained in:
stelar7 2025-04-25 18:12:28 +02:00 committed by Jelle Raaijmakers
commit 577f799240
Notes: github-actions[bot] 2025-04-28 09:32:51 +00:00
4 changed files with 8 additions and 7 deletions

View file

@ -250,7 +250,7 @@ WebIDL::ExceptionOr<GC::Ref<IDBRequest>> IDBObjectStore::add_or_put(GC::Ref<IDBO
return WebIDL::DataError::create(realm, "Store uses in-line keys and key was given"_string); return WebIDL::DataError::create(realm, "Store uses in-line keys and key was given"_string);
// 7. If store uses out-of-line keys and has no key generator and key was not given, throw a "DataError" DOMException. // 7. If store uses out-of-line keys and has no key generator and key was not given, throw a "DataError" DOMException.
if (store.uses_out_of_line_keys() && !store.key_generator().has_value() && !key_was_given) if (store.uses_out_of_line_keys() && !store.uses_a_key_generator() && !key_was_given)
return WebIDL::DataError::create(realm, "Store uses out-of-line keys and has no key generator and key was not given"_string); return WebIDL::DataError::create(realm, "Store uses out-of-line keys and has no key generator and key was not given"_string);
GC::Ptr<Key> key_value; GC::Ptr<Key> key_value;
@ -291,7 +291,7 @@ WebIDL::ExceptionOr<GC::Ref<IDBRequest>> IDBObjectStore::add_or_put(GC::Ref<IDBO
// 4. Otherwise (kpk is failure): // 4. Otherwise (kpk is failure):
else { else {
// 1. If store does not have a key generator, throw a "DataError" DOMException. // 1. If store does not have a key generator, throw a "DataError" DOMException.
if (!store.key_generator().has_value()) if (!store.uses_a_key_generator())
return WebIDL::DataError::create(realm, "Store does not have a key generator"_string); return WebIDL::DataError::create(realm, "Store does not have a key generator"_string);
// 2. Otherwise, if check that a key could be injected into a value with clone and stores key path return false, throw a "DataError" DOMException. // 2. Otherwise, if check that a key could be injected into a value with clone and stores key path return false, throw a "DataError" DOMException.

View file

@ -31,7 +31,7 @@ public:
// https://w3c.github.io/IndexedDB/#dom-idbobjectstore-autoincrement // https://w3c.github.io/IndexedDB/#dom-idbobjectstore-autoincrement
// The autoIncrement getter steps are to return true if thiss object store has a key generator, and false otherwise. // The autoIncrement getter steps are to return true if thiss object store has a key generator, and false otherwise.
bool auto_increment() const { return m_store->key_generator().has_value(); } bool auto_increment() const { return m_store->uses_a_key_generator(); }
JS::Value key_path() const; JS::Value key_path() const;
String name() const { return m_name; } String name() const { return m_name; }
WebIDL::ExceptionOr<void> set_name(String const& value); WebIDL::ExceptionOr<void> set_name(String const& value);

View file

@ -1220,7 +1220,7 @@ GC::Ref<IDBRequest> asynchronously_execute_a_request(JS::Realm& realm, IDBReques
ErrorOr<u64> generate_a_key(GC::Ref<ObjectStore> store) ErrorOr<u64> generate_a_key(GC::Ref<ObjectStore> store)
{ {
// 1. Let generator be stores key generator. // 1. Let generator be stores key generator.
auto generator = store->key_generator().value(); auto& generator = store->key_generator();
// 2. Let key be generators current number. // 2. Let key be generators current number.
auto key = generator.current_number(); auto key = generator.current_number();
@ -1253,7 +1253,7 @@ void possibly_update_the_key_generator(GC::Ref<ObjectStore> store, GC::Ref<Key>
u64 value = floor(temp_value); u64 value = floor(temp_value);
// 5. Let generator be stores key generator. // 5. Let generator be stores key generator.
auto generator = store->key_generator().value(); auto& generator = store->key_generator();
// 6. If value is greater than or equal to generators current number, then set generators current number to value + 1. // 6. If value is greater than or equal to generators current number, then set generators current number to value + 1.
if (value >= generator.current_number()) if (value >= generator.current_number())
@ -1324,7 +1324,7 @@ void delete_records_from_an_object_store(GC::Ref<ObjectStore> store, GC::Ref<IDB
WebIDL::ExceptionOr<GC::Ptr<Key>> store_a_record_into_an_object_store(JS::Realm& realm, GC::Ref<ObjectStore> store, JS::Value value, GC::Ptr<Key> key, bool no_overwrite) WebIDL::ExceptionOr<GC::Ptr<Key>> store_a_record_into_an_object_store(JS::Realm& realm, GC::Ref<ObjectStore> store, JS::Value value, GC::Ptr<Key> key, bool no_overwrite)
{ {
// 1. If store uses a key generator, then: // 1. If store uses a key generator, then:
if (store->key_generator().has_value()) { if (store->uses_a_key_generator()) {
// 1. If key is undefined, then: // 1. If key is undefined, then:
if (key == nullptr) { if (key == nullptr) {
// 1. Let key be the result of generating a key for store. // 1. Let key be the result of generating a key for store.

View file

@ -43,7 +43,8 @@ public:
Optional<KeyPath> key_path() const { return m_key_path; } Optional<KeyPath> key_path() const { return m_key_path; }
bool uses_inline_keys() const { return m_key_path.has_value(); } bool uses_inline_keys() const { return m_key_path.has_value(); }
bool uses_out_of_line_keys() const { return !m_key_path.has_value(); } bool uses_out_of_line_keys() const { return !m_key_path.has_value(); }
Optional<KeyGenerator> key_generator() const { return m_key_generator; } KeyGenerator& key_generator() { return *m_key_generator; }
bool uses_a_key_generator() const { return m_key_generator.has_value(); }
AK::HashMap<String, GC::Ref<Index>>& index_set() { return m_indexes; } AK::HashMap<String, GC::Ref<Index>>& index_set() { return m_indexes; }
GC::Ref<Database> database() const { return m_database; } GC::Ref<Database> database() const { return m_database; }