瀏覽代碼

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.
Andreas Kling 11 月之前
父節點
當前提交
5606ce412e
共有 1 個文件被更改,包括 5 次插入4 次删除
  1. 5 4
      Userland/Libraries/LibWeb/HTML/HTMLLinkElement.cpp

+ 5 - 4
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<Core::Promise<Web::Platform::DecodedImage>> decode_favicon(ReadonlyBytes favicon_data, URL::URL const& favicon_url, JS::GCPtr<Navigable> navigable)
+static NonnullRefPtr<Core::Promise<Web::Platform::DecodedImage>> decode_favicon(ReadonlyBytes favicon_data, URL::URL const& favicon_url, JS::NonnullGCPtr<DOM::Document> 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<void> {
+    auto on_successful_decode = [document = JS::Handle(document)](Web::Platform::DecodedImage& decoded_image) -> ErrorOr<void> {
         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<void> 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) {
         });