From 5606ce412e1d946dcd59a85ed50e429efdde863f Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Wed, 21 Aug 2024 14:52:51 +0200 Subject: [PATCH] LibWeb: Handle document/navigable disconnection during favicon decode If the document is disconnected from the navigable by the time a favicon decode completes successfully, we don't want to show the favicon for whatever document is now loaded in the navigable. Fix this by deferring getting the navigable until after the decode has completed. --- Userland/Libraries/LibWeb/HTML/HTMLLinkElement.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Userland/Libraries/LibWeb/HTML/HTMLLinkElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLLinkElement.cpp index a241db5f71..bc80c11743 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLLinkElement.cpp +++ b/Userland/Libraries/LibWeb/HTML/HTMLLinkElement.cpp @@ -520,16 +520,17 @@ void HTMLLinkElement::resource_did_load_favicon() document().check_favicon_after_loading_link_resource(); } -static NonnullRefPtr> decode_favicon(ReadonlyBytes favicon_data, URL::URL const& favicon_url, JS::GCPtr navigable) +static NonnullRefPtr> decode_favicon(ReadonlyBytes favicon_data, URL::URL const& favicon_url, JS::NonnullGCPtr document) { auto on_failed_decode = [favicon_url]([[maybe_unused]] Error& error) { dbgln_if(IMAGE_DECODER_DEBUG, "Failed to decode favicon {}: {}", favicon_url, error); }; - auto on_successful_decode = [navigable = JS::Handle(*navigable)](Web::Platform::DecodedImage& decoded_image) -> ErrorOr { + auto on_successful_decode = [document = JS::Handle(document)](Web::Platform::DecodedImage& decoded_image) -> ErrorOr { auto favicon_bitmap = decoded_image.frames[0].bitmap; dbgln_if(IMAGE_DECODER_DEBUG, "Decoded favicon, {}", favicon_bitmap->size()); + auto navigable = document->navigable(); if (navigable && navigable->is_traversable()) navigable->traversable_navigable()->page().client().page_did_change_favicon(*favicon_bitmap); @@ -547,7 +548,7 @@ bool HTMLLinkElement::load_favicon_and_use_if_window_is_active() return false; // FIXME: Refactor the caller(s) to handle the async nature of image loading - auto promise = decode_favicon(resource()->encoded_data(), resource()->url(), navigable()); + auto promise = decode_favicon(resource()->encoded_data(), resource()->url(), document()); auto result = promise->await(); return !result.is_error(); } @@ -583,7 +584,7 @@ WebIDL::ExceptionOr HTMLLinkElement::load_fallback_favicon_if_needed(JS::N auto global = JS::NonnullGCPtr { realm.global_object() }; auto process_body = JS::create_heap_function(realm.heap(), [document, request](ByteBuffer body) { - (void)decode_favicon(body, request->url(), document->navigable()); + (void)decode_favicon(body, request->url(), document); }); auto process_body_error = JS::create_heap_function(realm.heap(), [](JS::Value) { });