From da5fca15ee0104f7dd5c16f5a8d878f4819ac938 Mon Sep 17 00:00:00 2001 From: Luke Wilde Date: Tue, 22 Jul 2025 17:03:34 +0100 Subject: [PATCH] LibWeb: Only expose performance.{timing,navigation} on Window They are only valid in a Window context, and the spec only exposes them in Window contexts. Fixes workers crashing on: - https://web.whatsapp.com/ - https://pro.kraken.com/app/trade/btc-usd --- .../LibWeb/HighResolutionTime/Performance.idl | 8 +---- .../PerformanceExtensions.idl | 8 +++++ .../BindingsGenerator/IDLGenerators.cpp | 25 ++++++++++++- ...vigation-not-exposed-outside-of-window.txt | 6 ++++ ...igation-not-exposed-outside-of-window.html | 36 +++++++++++++++++++ 5 files changed, 75 insertions(+), 8 deletions(-) create mode 100644 Libraries/LibWeb/NavigationTiming/PerformanceExtensions.idl create mode 100644 Tests/LibWeb/Text/expected/performance-timing-and-navigation-not-exposed-outside-of-window.txt create mode 100644 Tests/LibWeb/Text/input/performance-timing-and-navigation-not-exposed-outside-of-window.html diff --git a/Libraries/LibWeb/HighResolutionTime/Performance.idl b/Libraries/LibWeb/HighResolutionTime/Performance.idl index 0ee1307bde7..c5e32f3e466 100644 --- a/Libraries/LibWeb/HighResolutionTime/Performance.idl +++ b/Libraries/LibWeb/HighResolutionTime/Performance.idl @@ -1,5 +1,6 @@ #import #import +#import #import #import #import @@ -34,11 +35,4 @@ interface Performance : EventTarget { PerformanceEntryList getEntries(); PerformanceEntryList getEntriesByType(DOMString type); PerformanceEntryList getEntriesByName(DOMString name, optional DOMString type); - - // https://w3c.github.io/navigation-timing/#extensions-to-the-performance-interface - // Obsolete "Navigation Timing" extensions to the Performance interface - [SameObject] - readonly attribute PerformanceTiming timing; - [SameObject] - readonly attribute PerformanceNavigation navigation; }; diff --git a/Libraries/LibWeb/NavigationTiming/PerformanceExtensions.idl b/Libraries/LibWeb/NavigationTiming/PerformanceExtensions.idl new file mode 100644 index 00000000000..f62b7a002c9 --- /dev/null +++ b/Libraries/LibWeb/NavigationTiming/PerformanceExtensions.idl @@ -0,0 +1,8 @@ +// https://w3c.github.io/navigation-timing/#extensions-to-the-performance-interface +[Exposed=Window] +partial interface Performance { + [SameObject] + readonly attribute PerformanceTiming timing; + [SameObject] + readonly attribute PerformanceNavigation navigation; +}; diff --git a/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp b/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp index de3de012731..f8bd60ee875 100644 --- a/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp +++ b/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp @@ -3136,6 +3136,19 @@ static void collect_attribute_values_of_an_inheritance_stack(SourceGenerator& fu // FIXME: Check if the attributes are exposed. + // NOTE: Add more specified exposed global interface groups when needed. + StringBuilder window_exposed_only_members_builder; + SourceGenerator window_exposed_only_members_generator { window_exposed_only_members_builder, function_generator.clone_mapping() }; + auto generator_for_member = [&](auto const& name, auto& extended_attributes) -> SourceGenerator { + if (auto maybe_exposed = extended_attributes.get("Exposed"); maybe_exposed.has_value()) { + auto exposed_to = MUST(IDL::parse_exposure_set(name, *maybe_exposed)); + if (exposed_to == IDL::ExposedTo::Window) { + return window_exposed_only_members_generator.fork(); + } + } + return function_generator.fork(); + }; + // 1. Let id be the identifier of attr. // 2. Let value be the result of running the getter steps of attr with object as this. @@ -3154,7 +3167,7 @@ static void collect_attribute_values_of_an_inheritance_stack(SourceGenerator& fu if (!attribute.type->is_json(interface_in_chain)) continue; - auto attribute_generator = function_generator.fork(); + auto attribute_generator = generator_for_member(attribute.name, attribute.extended_attributes); auto return_value_name = ByteString::formatted("{}_retval", attribute.name.to_snakecase()); attribute_generator.set("attribute.name", attribute.name); @@ -3211,6 +3224,16 @@ static void collect_attribute_values_of_an_inheritance_stack(SourceGenerator& fu constant_generator.append(R"~~~( MUST(result->create_data_property("@constant.name@"_fly_string, constant_@constant.name@_value)); +)~~~"); + } + + if (!window_exposed_only_members_generator.as_string_view().is_empty()) { + auto window_only_property_declarations = function_generator.fork(); + window_only_property_declarations.set("defines", window_exposed_only_members_generator.as_string_view()); + window_only_property_declarations.append(R"~~~( + if (is(realm.global_object())) { +@defines@ + } )~~~"); } } diff --git a/Tests/LibWeb/Text/expected/performance-timing-and-navigation-not-exposed-outside-of-window.txt b/Tests/LibWeb/Text/expected/performance-timing-and-navigation-not-exposed-outside-of-window.txt new file mode 100644 index 00000000000..066b54a3802 --- /dev/null +++ b/Tests/LibWeb/Text/expected/performance-timing-and-navigation-not-exposed-outside-of-window.txt @@ -0,0 +1,6 @@ +(window) navigation: object +(window) timing: object +(window) performance JSON: {"timeOrigin":[removed-potentially-flaky-time-value],"timing":{"navigationStart":[removed-potentially-flaky-time-value],"unloadEventStart":[removed-potentially-flaky-time-value],"unloadEventEnd":[removed-potentially-flaky-time-value],"redirectStart":[removed-potentially-flaky-time-value],"redirectEnd":[removed-potentially-flaky-time-value],"fetchStart":[removed-potentially-flaky-time-value],"domainLookupStart":[removed-potentially-flaky-time-value],"domainLookupEnd":[removed-potentially-flaky-time-value],"connectStart":[removed-potentially-flaky-time-value],"connectEnd":[removed-potentially-flaky-time-value],"secureConnectionStart":[removed-potentially-flaky-time-value],"requestStart":[removed-potentially-flaky-time-value],"responseStart":[removed-potentially-flaky-time-value],"responseEnd":[removed-potentially-flaky-time-value],"domLoading":[removed-potentially-flaky-time-value],"domInteractive":[removed-potentially-flaky-time-value],"domContentLoadedEventStart":[removed-potentially-flaky-time-value],"domContentLoadedEventEnd":[removed-potentially-flaky-time-value],"domComplete":[removed-potentially-flaky-time-value],"loadEventStart":[removed-potentially-flaky-time-value],"loadEventEnd":[removed-potentially-flaky-time-value]},"navigation":{"type":[removed-potentially-flaky-time-value],"redirectCount":[removed-potentially-flaky-time-value],"TYPE_NAVIGATE":0,"TYPE_RELOAD":1,"TYPE_BACK_FORWARD":2,"TYPE_RESERVED":255}} +(worker) navigation: undefined +(worker) timing: undefined +(worker) performance JSON: {"timeOrigin":[removed-potentially-flaky-time-value]} diff --git a/Tests/LibWeb/Text/input/performance-timing-and-navigation-not-exposed-outside-of-window.html b/Tests/LibWeb/Text/input/performance-timing-and-navigation-not-exposed-outside-of-window.html new file mode 100644 index 00000000000..57d65f4151c --- /dev/null +++ b/Tests/LibWeb/Text/input/performance-timing-and-navigation-not-exposed-outside-of-window.html @@ -0,0 +1,36 @@ + + + +