From d91d6ee20593d857974fea818a9faa190d6a4ed9 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Wed, 3 Apr 2024 20:17:09 +0200 Subject: [PATCH] LibWeb: Stop leaking entire realms via Blob URLs This patch implements the File API spec's supplemental steps for document's "unloading document cleanup steps" so that we now remove blob URLs associated with the document's relevant settings object when the document is being unloaded. Fixes two realm leaks when running our test suite. --- Userland/Libraries/LibWeb/DOM/Document.cpp | 5 ++++- .../Libraries/LibWeb/FileAPI/BlobURLStore.cpp | 17 +++++++++++++++++ .../Libraries/LibWeb/FileAPI/BlobURLStore.h | 2 ++ 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/Userland/Libraries/LibWeb/DOM/Document.cpp b/Userland/Libraries/LibWeb/DOM/Document.cpp index 9e9281f5473..9549165a757 100644 --- a/Userland/Libraries/LibWeb/DOM/Document.cpp +++ b/Userland/Libraries/LibWeb/DOM/Document.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2023, Andreas Kling + * Copyright (c) 2018-2024, Andreas Kling * Copyright (c) 2021-2023, Linus Groh * Copyright (c) 2021-2023, Luke Wilde * Copyright (c) 2021-2023, Sam Atkins @@ -52,6 +52,7 @@ #include #include #include +#include #include #include #include @@ -2988,6 +2989,8 @@ void Document::run_unloading_cleanup_steps() // 2. Clear window's map of active timers. window->clear_map_of_active_timers(); } + + FileAPI::run_unloading_cleanup_steps(*this); } // https://html.spec.whatwg.org/multipage/document-lifecycle.html#destroy-a-document diff --git a/Userland/Libraries/LibWeb/FileAPI/BlobURLStore.cpp b/Userland/Libraries/LibWeb/FileAPI/BlobURLStore.cpp index 08e2adb9e7b..fdc119592fb 100644 --- a/Userland/Libraries/LibWeb/FileAPI/BlobURLStore.cpp +++ b/Userland/Libraries/LibWeb/FileAPI/BlobURLStore.cpp @@ -1,5 +1,6 @@ /* * Copyright (c) 2023, Tim Flynn + * Copyright (c) 2024, Andreas Kling * * SPDX-License-Identifier: BSD-2-Clause */ @@ -7,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -89,4 +91,19 @@ ErrorOr remove_entry_from_blob_url_store(StringView url) return {}; } +// https://w3c.github.io/FileAPI/#lifeTime +void run_unloading_cleanup_steps(JS::NonnullGCPtr document) +{ + // 1. Let environment be the Document's relevant settings object. + auto& environment = document->relevant_settings_object(); + + // 2. Let store be the user agent’s blob URL store; + auto& store = FileAPI::blob_url_store(); + + // 3. Remove from store any entries for which the value's environment is equal to environment. + store.remove_all_matching([&](auto&, auto& value) { + return value.environment == &environment; + }); +} + } diff --git a/Userland/Libraries/LibWeb/FileAPI/BlobURLStore.h b/Userland/Libraries/LibWeb/FileAPI/BlobURLStore.h index 6e83cd076d1..13f39c824c2 100644 --- a/Userland/Libraries/LibWeb/FileAPI/BlobURLStore.h +++ b/Userland/Libraries/LibWeb/FileAPI/BlobURLStore.h @@ -28,4 +28,6 @@ ErrorOr generate_new_blob_url(); ErrorOr add_entry_to_blob_url_store(JS::NonnullGCPtr object); ErrorOr remove_entry_from_blob_url_store(StringView url); +void run_unloading_cleanup_steps(JS::NonnullGCPtr); + }