From 324dacbc5d8496b2d8739c7f51e276b3a6570537 Mon Sep 17 00:00:00 2001 From: Linus Groh Date: Sat, 11 Mar 2023 18:06:11 +0000 Subject: [PATCH] LibWeb/HTML: Propagate OOM errors from Window::{local,session}_storage() This requires a bit of error type conversion glue as HashMap::try_ensure expects the callback to return ErrorOr like the function itself does. --- Userland/Libraries/LibWeb/HTML/Window.cpp | 28 ++++++++++++------- Userland/Libraries/LibWeb/HTML/Window.h | 4 +-- .../WebContent/ConnectionFromClient.cpp | 8 +++--- 3 files changed, 24 insertions(+), 16 deletions(-) diff --git a/Userland/Libraries/LibWeb/HTML/Window.cpp b/Userland/Libraries/LibWeb/HTML/Window.cpp index caab16f09e..5272ad1e98 100644 --- a/Userland/Libraries/LibWeb/HTML/Window.cpp +++ b/Userland/Libraries/LibWeb/HTML/Window.cpp @@ -705,27 +705,35 @@ void Window::fire_a_page_transition_event(DeprecatedFlyString const& event_name, } // https://html.spec.whatwg.org/multipage/webstorage.html#dom-localstorage -JS::NonnullGCPtr Window::local_storage() +WebIDL::ExceptionOr> Window::local_storage() { // FIXME: Implement according to spec. + auto& vm = this->vm(); static HashMap> local_storage_per_origin; - auto storage = local_storage_per_origin.ensure(associated_document().origin(), [this]() -> JS::Handle { - return *HTML::Storage::create(realm()).release_value_but_fixme_should_propagate_errors(); - }); - return *storage; + auto storage = TRY_OR_THROW_OOM(vm, local_storage_per_origin.try_ensure(associated_document().origin(), [this]() -> ErrorOr> { + auto storage_or_exception = HTML::Storage::create(realm()); + if (storage_or_exception.is_exception()) + return Error::from_errno(ENOMEM); + return *storage_or_exception.release_value(); + })); + return JS::NonnullGCPtr { *storage }; } // https://html.spec.whatwg.org/multipage/webstorage.html#dom-sessionstorage -JS::NonnullGCPtr Window::session_storage() +WebIDL::ExceptionOr> Window::session_storage() { // FIXME: Implement according to spec. + auto& vm = this->vm(); static HashMap> session_storage_per_origin; - auto storage = session_storage_per_origin.ensure(associated_document().origin(), [this]() -> JS::Handle { - return *HTML::Storage::create(realm()).release_value_but_fixme_should_propagate_errors(); - }); - return *storage; + auto storage = TRY_OR_THROW_OOM(vm, session_storage_per_origin.try_ensure(associated_document().origin(), [this]() -> ErrorOr> { + auto storage_or_exception = HTML::Storage::create(realm()); + if (storage_or_exception.is_exception()) + return Error::from_errno(ENOMEM); + return *storage_or_exception.release_value(); + })); + return JS::NonnullGCPtr { *storage }; } // https://html.spec.whatwg.org/multipage/interaction.html#transient-activation diff --git a/Userland/Libraries/LibWeb/HTML/Window.h b/Userland/Libraries/LibWeb/HTML/Window.h index f3f770a68f..c855239453 100644 --- a/Userland/Libraries/LibWeb/HTML/Window.h +++ b/Userland/Libraries/LibWeb/HTML/Window.h @@ -115,8 +115,8 @@ public: void fire_a_page_transition_event(DeprecatedFlyString const& event_name, bool persisted); - JS::NonnullGCPtr local_storage(); - JS::NonnullGCPtr session_storage(); + WebIDL::ExceptionOr> local_storage(); + WebIDL::ExceptionOr> session_storage(); void start_an_idle_period(); diff --git a/Userland/Services/WebContent/ConnectionFromClient.cpp b/Userland/Services/WebContent/ConnectionFromClient.cpp index d2d6a79db2..3e7b27ef8e 100644 --- a/Userland/Services/WebContent/ConnectionFromClient.cpp +++ b/Userland/Services/WebContent/ConnectionFromClient.cpp @@ -258,8 +258,8 @@ void ConnectionFromClient::debug_request(DeprecatedString const& request, Deprec } if (request == "dump-local-storage") { - if (auto* doc = page().top_level_browsing_context().active_document()) - doc->window().local_storage()->dump(); + if (auto* document = page().top_level_browsing_context().active_document()) + document->window().local_storage().release_value_but_fixme_should_propagate_errors()->dump(); } } @@ -549,14 +549,14 @@ void ConnectionFromClient::set_window_size(Gfx::IntSize size) Messages::WebContentServer::GetLocalStorageEntriesResponse ConnectionFromClient::get_local_storage_entries() { auto* document = page().top_level_browsing_context().active_document(); - auto local_storage = document->window().local_storage(); + auto local_storage = document->window().local_storage().release_value_but_fixme_should_propagate_errors(); return local_storage->map(); } Messages::WebContentServer::GetSessionStorageEntriesResponse ConnectionFromClient::get_session_storage_entries() { auto* document = page().top_level_browsing_context().active_document(); - auto session_storage = document->window().session_storage(); + auto session_storage = document->window().session_storage().release_value_but_fixme_should_propagate_errors(); return session_storage->map(); }