CVE-2026-91715
Overview
Background
- V8 code cache (cached metadata)
- Serialized V8 compilation data that Blink stores for a script response and later hands back to V8 (for example as
cached_metadataduring script streaming) so V8 can skip compiling the script again. - Service-worker-mediated subresource
- A script request answered by a controlling service worker through
respondWith, whichResourceResponse::WasFetchedViaServiceWorker()/head->was_fetched_via_service_workerreports. - Existing SW code-cache routing
- Before the patch, the context comments and tests already sent passthrough SW responses (
respondWith(fetch(evt.request.url))) to the site-isolated code cache andcache.matchresponses to the Cache Storage code cache. The tests namedDoesNotSendMetadataToPlatformWhenFetchedViaServiceWorkerWith{DifferentURL,SyntheticCache,DifferentURLCache}Responsealready excluded synthetic and different-URL responses. - `ServiceWorkerCodeCache`
- A new runtime-enabled feature in
runtime_enabled_features.json5, with nostatusand so disabled by default (as the commit message says), that gates every V8 code-cache path for SW-mediated subresources.
Root Cause Analysis
Verify before building a PoC
What the commit does not establish: Impact says the advisory gives no severity, but it states high. The advisory does not name the renderer process; that is inferred. Otherwise it correctly notes this is a default-off kill switch citing four bugs, with the defect not shown.
This commit only partly matches the advisory: it is a kill-switch mitigation that lists four bugs (558367547, 546413288, 547815507, 558342353), and it does not show the specific defect behind the type confusion. Before the patch, Blink did not code-cache SW responses unconditionally: synthetic and different-URL SW responses were already excluded, and only passthrough responses (site-isolated cache) and cache.match responses (Cache Storage cache) could produce or consume V8 code cache, as the existing tests and the context comment “Non-ServiceWorker scripts and passthrough SW responses use the site isolated code cache” show.
The patch tightens this: with ServiceWorkerCodeCache off by default, any response with WasFetchedViaServiceWorker() set gets a NullCachedMetadataSender, false from ShouldUseIsolatedCodeCache, an early return in ScriptResource right after cached_metadata_handler_ = nullptr (so no handler is created), and a cached_metadata.reset() in script_streamer.cc, placed before the existing WebAssembly MIME check. Each guard runs before metadata is sent or consumed, which removes the whole SW code-cache surface rather than repairing one invariant. The diff therefore does not show which invariant in that path was broken or how it led to a type confusion, and any specific mechanism, such as compiled data being applied to a mismatched script or cache-type confusion, is (inferred).
ServiceWorkerCodeCache) instead of patching the passthrough and Cache Storage code-cache paths that were still allowed. That fits several related bugs in that code-cache surface, which the commit references.Attack Path
- Control a service worker Any web origin can register a service worker that intercepts its own pages’ subresource script fetches. This is the default web platform, with no special flags.
- Serve a still-eligible SW response
The worker answers a script request in a way that was still eligible for code caching before the patch, such as a passthrough
fetchof the same URL or acache.matchCache Storage response. Synthetic and different-URL responses were already excluded. - Drive code-cache produce/consume
Loading that script makes Blink create a cache handler and sender (
ScriptResource,CachedMetadataSender) and pass storedcached_metadatato V8 throughscript_streamer.cc. These are exactly the paths the patch now cuts off for SW responses. - Trigger the type confusion A defect somewhere in this SW code-cache path causes the “Type confusion in ServiceWorker” the advisory reports. The concrete trigger, the confused types and any memory-corruption primitive are not in the diff (inferred).
Impact Assessment
Changed Functions
| Function | Change | Notes |
|---|---|---|
ifthird_party/blink/renderer/bindings/core/v8/script_streamer.cc |
modified | |
ServiceWorkerV8CodeCacheForCacheStorageTestcontent/browser/service_worker/service_worker_browsertest.cc |
modified | |
ServiceWorkerV8CodeCacheForCacheStorageTestcontent/browser/service_worker/service_worker_browsertest.cc |
modified | |
TESTthird_party/blink/renderer/core/loader/resource/script_resource_test.cc |
modified |
Files Changed
third_party/blink/renderer/platform/runtime_enabled_features.json5third_party/blink/renderer/platform/loader/fetch/url_loader/cached_metadata_handler_test.ccthird_party/blink/renderer/bindings/core/v8/script_streamer.ccthird_party/blink/renderer/core/loader/resource/script_resource.cccontent/browser/service_worker/service_worker_browsertest.ccthird_party/blink/renderer/platform/loader/fetch/url_loader/cached_metadata_handler.ccthird_party/blink/renderer/core/loader/resource/script_resource_test.cc
Audit Directions
- Remaining SW code-cache routesThe flag is only a mitigation. Review the passthrough-to-isolated-cache and
cache.match-to-Cache-Storage routing incached_metadata_handler.cc, plus the consumers inScriptResourceandscript_streamer.cc. Look for cases where stored metadata could be applied to a response or script type other than the one that produced it. These paths come back ifServiceWorkerCodeCacheis ever enabled. - Kill-switch completenessCheck every other place that reads or writes V8 code cache for a response, such as module scripts, worker scripts and
mojom::blink::CodeCacheTypeWebAssembly paths, for aWasFetchedViaServiceWorker()check. A consumer the flag misses would leave the surface reachable. - Response provenance vs. cache identityWherever a cache entry is chosen by URL or cache name but the bytes come from a service worker or Cache Storage, check that the producer and consumer agree on response identity and script kind before deserializing.
Patch
From c0b5e81749361a9c8a79990f2c721a16d141882c Mon Sep 17 00:00:00 2001
From: Takashi Nakayama <tnak@chromium.org>
Date: Thu, 10 Sep 2026 00:32:02 -0700
Subject: [PATCH] ServiceWorker: Add feature flag to disable Code Cache
This CL adds a new runtime enabled feature, `ServiceWorkerCodeCache` to
disable Code Caching for subresource requests through Service Workers.
The new feature is disabled by default.
Bug: 558367547, 546413288, 547815507, 558342353
Change-Id: I2a3b7fbf8c489eec00bce668abb3a7cf438d9f44
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/8377021
Reviewed-by: Yoshisato Yanagisawa <yyanagisawa@chromium.org>
Reviewed-by: Shunya Shishido <sisidovski@chromium.org>
Commit-Queue: Takashi Nakayama <tnak@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1695233}
---
diff --git a/third_party/blink/renderer/bindings/core/v8/script_streamer.cc b/third_party/blink/renderer/bindings/core/v8/script_streamer.cc
index aabdaa9e..615c445 100644
--- a/third_party/blink/renderer/bindings/core/v8/script_streamer.cc
+++ b/third_party/blink/renderer/bindings/core/v8/script_streamer.cc
@@ -58,6 +58,7 @@
#include "third_party/blink/renderer/platform/loader/fetch/response_body_loader.h"
#include "third_party/blink/renderer/platform/loader/fetch/script_cached_metadata_handler.h"
#include "third_party/blink/renderer/platform/network/mime/mime_type_registry.h"
+#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h"
#include "third_party/blink/renderer/platform/scheduler/public/worker_pool.h"
@@ -1874,6 +1875,11 @@
return false;
}
+ if (!RuntimeEnabledFeatures::ServiceWorkerCodeCacheEnabled() &&
+ head->was_fetched_via_service_worker) {
+ cached_metadata.reset();
+ }
+
if (is_valid_wasm_mime_type) {
// TODO(https://crbug.com/42204365): Add support for code caching.
// For now, we clear cached_metadata to avoid unintended side-effects.
diff --git a/third_party/blink/renderer/core/loader/resource/script_resource.cc b/third_party/blink/renderer/core/loader/resource/script_resource.cc
index 39a58fe..8b9f1616 100644
--- a/third_party/blink/renderer/core/loader/resource/script_resource.cc
+++ b/third_party/blink/renderer/core/loader/resource/script_resource.cc
@@ -59,6 +59,7 @@
#include "third_party/blink/renderer/platform/loader/fetch/webui_bundled_cached_metadata_handler.h"
#include "third_party/blink/renderer/platform/loader/subresource_integrity.h"
#include "third_party/blink/renderer/platform/network/mime/mime_type_registry.h"
+#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/weborigin/scheme_registry.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
#include "third_party/blink/renderer/platform/wtf/shared_buffer.h"
@@ -411,6 +412,10 @@
}
cached_metadata_handler_ = nullptr;
+ if (response.WasFetchedViaServiceWorker() &&
+ !RuntimeEnabledFeatures::ServiceWorkerCodeCacheEnabled()) {
+ return;
+ }
// Currently we support the metadata caching only for HTTP family and any
// schemes defined by SchemeRegistry as requiring a hash check.
bool http_family = GetResourceRequest().Url().ProtocolIsInHttpFamily() &&
diff --git a/third_party/blink/renderer/platform/loader/fetch/url_loader/cached_metadata_handler.cc b/third_party/blink/renderer/platform/loader/fetch/url_loader/cached_metadata_handler.cc
index 3707f3fc..5ef2f37d 100644
--- a/third_party/blink/renderer/platform/loader/fetch/url_loader/cached_metadata_handler.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/url_loader/cached_metadata_handler.cc
@@ -12,6 +12,7 @@
#include "third_party/blink/public/platform/web_url.h"
#include "third_party/blink/renderer/platform/loader/fetch/code_cache_host.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_response.h"
+#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
namespace blink {
@@ -131,6 +132,11 @@
const ResourceResponse& response,
mojom::blink::CodeCacheType code_cache_type,
scoped_refptr<const SecurityOrigin> requestor_origin) {
+ if (!RuntimeEnabledFeatures::ServiceWorkerCodeCacheEnabled() &&
+ response.WasFetchedViaServiceWorker()) {
+ return std::make_unique<NullCachedMetadataSender>();
+ }
+
// Non-ServiceWorker scripts and passthrough SW responses use the site
// isolated code cache.
if (!response.WasFetchedViaServiceWorker() ||
@@ -171,6 +177,11 @@
bool ShouldUseIsolatedCodeCache(
mojom::blink::RequestContextType request_context,
const ResourceResponse& response) {
+ if (!RuntimeEnabledFeatures::ServiceWorkerCodeCacheEnabled() &&
+ response.WasFetchedViaServiceWorker()) {
+ return false;
+ }
+
// Service worker script has its own code cache.
if (request_context == mojom::blink::RequestContextType::SERVICE_WORKER)
return false;
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5
index 626e074..85ea1fb 100644
--- a/third_party/blink/renderer/platform/runtime_enabled_features.json5
+++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -5711,6 +5711,10 @@
status: "experimental",
},
{
+ // V8 Code Cache for resource requests passing through Service Worker.
+ name: "ServiceWorkerCodeCache",
+ },
+ {
// Support for Service Worker APIs in Dedicated Workers.
// See https://chromestatus.com/feature/6497653025931264
// See https://issues.chromium.org/issues/40364838
diff --git a/content/browser/service_worker/service_worker_browsertest.cc b/content/browser/service_worker/service_worker_browsertest.cc
index 42aaa111..01c4800 100644
--- a/content/browser/service_worker/service_worker_browsertest.cc
+++ b/content/browser/service_worker/service_worker_browsertest.cc
@@ -3399,7 +3399,10 @@
class ServiceWorkerV8CodeCacheForCacheStorageTest
: public ServiceWorkerBrowserTest {
public:
- ServiceWorkerV8CodeCacheForCacheStorageTest() = default;
+ ServiceWorkerV8CodeCacheForCacheStorageTest() {
+ feature_list_.InitAndEnableFeature(
+ blink::features::kServiceWorkerCodeCache);
+ }
ServiceWorkerV8CodeCacheForCacheStorageTest(
const ServiceWorkerV8CodeCacheForCacheStorageTest&) = delete;
@@ -3474,6 +3477,8 @@
partition->GetCacheStorageControl(), embedded_test_server()->base_url(),
std::string("cache_name"), embedded_test_server()->GetURL(kScriptUrl));
}
+
+ base::test::ScopedFeatureList feature_list_;
};
const char ServiceWorkerV8CodeCacheForCacheStorageTest::kPageUrl[] =
diff --git a/third_party/blink/renderer/core/loader/resource/script_resource_test.cc b/third_party/blink/renderer/core/loader/resource/script_resource_test.cc
index df582f1..4a1d54b 100644
--- a/third_party/blink/renderer/core/loader/resource/script_resource_test.cc
+++ b/third_party/blink/renderer/core/loader/resource/script_resource_test.cc
@@ -9,6 +9,7 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
#include "third_party/blink/renderer/platform/loader/fetch/url_loader/cached_metadata_handler.h"
+#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
#include "third_party/blink/renderer/platform/testing/task_environment.h"
#include "third_party/blink/renderer/platform/testing/testing_platform_support.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
@@ -323,5 +324,35 @@
enable_webui_bundled_code_caching(false);
}
+TEST(ScriptResourceTest, ServiceWorkerCodeCacheFlag) {
+ test::TaskEnvironment task_environment;
+ V8TestingScope scope;
+ const KURL url("https://www.example.com/sw-script.js");
+
+ {
+ ScopedServiceWorkerCodeCacheForTest scoped_feature(false);
+ ScriptResource* resource =
+ ScriptResource::CreateForTest(scope.GetIsolate(), url, Utf8Encoding());
+ ResourceResponse response(url);
+ response.SetHttpStatusCode(200);
+ response.SetWasFetchedViaServiceWorker(true);
+
+ resource->ResponseReceived(response);
+ EXPECT_FALSE(resource->CacheHandler());
+ }
+
+ {
+ ScopedServiceWorkerCodeCacheForTest scoped_feature(true);
+ ScriptResource* resource =
+ ScriptResource::CreateForTest(scope.GetIsolate(), url, Utf8Encoding());
+ ResourceResponse response(url);
+ response.SetHttpStatusCode(200);
+ response.SetWasFetchedViaServiceWorker(true);
+
+ resource->ResponseReceived(response);
+ EXPECT_TRUE(resource->CacheHandler());
+ }
+}
+
} // namespace
} // namespace blink
diff --git a/third_party/blink/renderer/platform/loader/fetch/url_loader/cached_metadata_handler_test.cc b/third_party/blink/renderer/platform/loader/fetch/url_loader/cached_metadata_handler_test.cc
index ba13a0e..a4320bb 100644
--- a/third_party/blink/renderer/platform/loader/fetch/url_loader/cached_metadata_handler_test.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/url_loader/cached_metadata_handler_test.cc
@@ -9,12 +9,14 @@
#include "components/persistent_cache/pending_backend.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink.h"
#include "third_party/blink/public/mojom/loader/code_cache.mojom-blink.h"
#include "third_party/blink/public/platform/url_conversion.h"
#include "third_party/blink/public/platform/web_url.h"
#include "third_party/blink/renderer/platform/loader/fetch/code_cache_host.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_request.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_response.h"
+#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
#include "third_party/blink/renderer/platform/testing/testing_platform_support.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
@@ -136,6 +138,7 @@
TEST(
CachedMetadataHandlerTest,
SendsMetadataToPlatformWhenFetchedViaServiceWorkerWithPassThroughResponse) {
+ ScopedServiceWorkerCodeCacheForTest scoped_feature(true);
MockGeneratedCodeCache mock_disk_cache;
// Equivalent to service worker calling respondWith(fetch(evt.request.url));
@@ -151,6 +154,7 @@
TEST(
CachedMetadataHandlerTest,
DoesNotSendMetadataToPlatformWhenFetchedViaServiceWorkerWithDifferentURLResponse) {
+ ScopedServiceWorkerCodeCacheForTest scoped_feature(true);
MockGeneratedCodeCache mock_disk_cache;
// Equivalent to service worker calling respondWith(fetch(some_different_url))
@@ -166,6 +170,7 @@
TEST(CachedMetadataHandlerTest,
SendsMetadataToPlatformWhenFetchedViaServiceWorkerWithCacheResponse) {
+ ScopedServiceWorkerCodeCacheForTest scoped_feature(true);
MockGeneratedCodeCache mock_disk_cache;
// Equivalent to service worker calling respondWith(cache.match(some_url));
@@ -179,9 +184,25 @@
EXPECT_EQ(1u, mock_disk_cache.CacheStorageCachedURLs().size());
}
+TEST(CachedMetadataHandlerTest,
+ DoesNotSendMetadataToPlatformWhenServiceWorkerCodeCacheDisabled) {
+ ScopedServiceWorkerCodeCacheForTest scoped_feature(false);
+ MockGeneratedCodeCache mock_disk_cache;
+
+ ResourceResponse response(CreateTestResourceResponse());
+ response.SetWasFetchedViaServiceWorker(true);
+ response.SetUrlListViaServiceWorker({response.CurrentRequestUrl()});
+ response.SetCacheStorageCacheName("dummy");
+
+ SendDataFor(response, &mock_disk_cache);
+ EXPECT_EQ(0u, mock_disk_cache.CachedURLs().size());
+ EXPECT_EQ(0u, mock_disk_cache.CacheStorageCachedURLs().size());
+}
+
TEST(
CachedMetadataHandlerTest,
DoesNotSendMetadataToPlatformWhenFetchedViaServiceWorkerWithSyntheticCacheResponse) {
+ ScopedServiceWorkerCodeCacheForTest scoped_feature(true);
MockGeneratedCodeCache mock_disk_cache;
// Equivalent to service worker calling
@@ -198,6 +219,7 @@
TEST(
CachedMetadataHandlerTest,
DoesNotSendMetadataToPlatformWhenFetchedViaServiceWorkerWithDifferentURLCacheResponse) {
+ ScopedServiceWorkerCodeCacheForTest scoped_feature(true);
MockGeneratedCodeCache mock_disk_cache;
// Equivalent to service worker calling
@@ -213,5 +235,23 @@
EXPECT_EQ(0u, mock_disk_cache.CacheStorageCachedURLs().size());
}
+TEST(CachedMetadataHandlerTest,
+ ShouldUseIsolatedCodeCacheRespectsServiceWorkerCodeCacheFlag) {
+ ResourceResponse response(CreateTestResourceResponse());
+ response.SetWasFetchedViaServiceWorker(true);
+ response.SetUrlListViaServiceWorker({response.CurrentRequestUrl()});
+
+ {
+ ScopedServiceWorkerCodeCacheForTest scoped_feature(false);
+ EXPECT_FALSE(ShouldUseIsolatedCodeCache(
+ mojom::blink::RequestContextType::SCRIPT, response));
+ }
+ {
+ ScopedServiceWorkerCodeCacheForTest scoped_feature(true);
+ EXPECT_TRUE(ShouldUseIsolatedCodeCache(
+ mojom::blink::RequestContextType::SCRIPT, response));
+ }
+}
+
} // namespace
} // namespace blink
Regression Test / PoC
diff --git a/content/browser/service_worker/service_worker_browsertest.cc b/content/browser/service_worker/service_worker_browsertest.cc
index 42aaa111..01c4800 100644
--- a/content/browser/service_worker/service_worker_browsertest.cc
+++ b/content/browser/service_worker/service_worker_browsertest.cc
@@ -3399,7 +3399,10 @@
class ServiceWorkerV8CodeCacheForCacheStorageTest
: public ServiceWorkerBrowserTest {
public:
- ServiceWorkerV8CodeCacheForCacheStorageTest() = default;
+ ServiceWorkerV8CodeCacheForCacheStorageTest() {
+ feature_list_.InitAndEnableFeature(
+ blink::features::kServiceWorkerCodeCache);
+ }
ServiceWorkerV8CodeCacheForCacheStorageTest(
const ServiceWorkerV8CodeCacheForCacheStorageTest&) = delete;
@@ -3474,6 +3477,8 @@
partition->GetCacheStorageControl(), embedded_test_server()->base_url(),
std::string("cache_name"), embedded_test_server()->GetURL(kScriptUrl));
}
+
+ base::test::ScopedFeatureList feature_list_;
};
const char ServiceWorkerV8CodeCacheForCacheStorageTest::kPageUrl[] =
diff --git a/third_party/blink/renderer/core/loader/resource/script_resource_test.cc b/third_party/blink/renderer/core/loader/resource/script_resource_test.cc
index df582f1..4a1d54b 100644
--- a/third_party/blink/renderer/core/loader/resource/script_resource_test.cc
+++ b/third_party/blink/renderer/core/loader/resource/script_resource_test.cc
@@ -9,6 +9,7 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
#include "third_party/blink/renderer/platform/loader/fetch/url_loader/cached_metadata_handler.h"
+#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
#include "third_party/blink/renderer/platform/testing/task_environment.h"
#include "third_party/blink/renderer/platform/testing/testing_platform_support.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
@@ -323,5 +324,35 @@
enable_webui_bundled_code_caching(false);
}
+TEST(ScriptResourceTest, ServiceWorkerCodeCacheFlag) {
+ test::TaskEnvironment task_environment;
+ V8TestingScope scope;
+ const KURL url("https://www.example.com/sw-script.js");
+
+ {
+ ScopedServiceWorkerCodeCacheForTest scoped_feature(false);
+ ScriptResource* resource =
+ ScriptResource::CreateForTest(scope.GetIsolate(), url, Utf8Encoding());
+ ResourceResponse response(url);
+ response.SetHttpStatusCode(200);
+ response.SetWasFetchedViaServiceWorker(true);
+
+ resource->ResponseReceived(response);
+ EXPECT_FALSE(resource->CacheHandler());
+ }
+
+ {
+ ScopedServiceWorkerCodeCacheForTest scoped_feature(true);
+ ScriptResource* resource =
+ ScriptResource::CreateForTest(scope.GetIsolate(), url, Utf8Encoding());
+ ResourceResponse response(url);
+ response.SetHttpStatusCode(200);
+ response.SetWasFetchedViaServiceWorker(true);
+
+ resource->ResponseReceived(response);
+ EXPECT_TRUE(resource->CacheHandler());
+ }
+}
+
} // namespace
} // namespace blink
diff --git a/third_party/blink/renderer/platform/loader/fetch/url_loader/cached_metadata_handler_test.cc b/third_party/blink/renderer/platform/loader/fetch/url_loader/cached_metadata_handler_test.cc
index ba13a0e..a4320bb 100644
--- a/third_party/blink/renderer/platform/loader/fetch/url_loader/cached_metadata_handler_test.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/url_loader/cached_metadata_handler_test.cc
@@ -9,12 +9,14 @@
#include "components/persistent_cache/pending_backend.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink.h"
#include "third_party/blink/public/mojom/loader/code_cache.mojom-blink.h"
#include "third_party/blink/public/platform/url_conversion.h"
#include "third_party/blink/public/platform/web_url.h"
#include "third_party/blink/renderer/platform/loader/fetch/code_cache_host.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_request.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_response.h"
+#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
#include "third_party/blink/renderer/platform/testing/testing_platform_support.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
@@ -136,6 +138,7 @@
TEST(
CachedMetadataHandlerTest,
SendsMetadataToPlatformWhenFetchedViaServiceWorkerWithPassThroughResponse) {
+ ScopedServiceWorkerCodeCacheForTest scoped_feature(true);
MockGeneratedCodeCache mock_disk_cache;
// Equivalent to service worker calling respondWith(fetch(evt.request.url));
@@ -151,6 +154,7 @@
TEST(
CachedMetadataHandlerTest,
DoesNotSendMetadataToPlatformWhenFetchedViaServiceWorkerWithDifferentURLResponse) {
+ ScopedServiceWorkerCodeCacheForTest scoped_feature(true);
MockGeneratedCodeCache mock_disk_cache;
// Equivalent to service worker calling respondWith(fetch(some_different_url))
@@ -166,6 +170,7 @@
TEST(CachedMetadataHandlerTest,
SendsMetadataToPlatformWhenFetchedViaServiceWorkerWithCacheResponse) {
+ ScopedServiceWorkerCodeCacheForTest scoped_feature(true);
MockGeneratedCodeCache mock_disk_cache;
// Equivalent to service worker calling respondWith(cache.match(some_url));
@@ -179,9 +184,25 @@
EXPECT_EQ(1u, mock_disk_cache.CacheStorageCachedURLs().size());
}
+TEST(CachedMetadataHandlerTest,
+ DoesNotSendMetadataToPlatformWhenServiceWorkerCodeCacheDisabled) {
+ ScopedServiceWorkerCodeCacheForTest scoped_feature(false);
+ MockGeneratedCodeCache mock_disk_cache;
+
+ ResourceResponse response(CreateTestResourceResponse());
+ response.SetWasFetchedViaServiceWorker(true);
+ response.SetUrlListViaServiceWorker({response.CurrentRequestUrl()});
+ response.SetCacheStorageCacheName("dummy");
+
+ SendDataFor(response, &mock_disk_cache);
+ EXPECT_EQ(0u, mock_disk_cache.CachedURLs().size());
+ EXPECT_EQ(0u, mock_disk_cache.CacheStorageCachedURLs().size());
+}
+
TEST(
CachedMetadataHandlerTest,
DoesNotSendMetadataToPlatformWhenFetchedViaServiceWorkerWithSyntheticCacheResponse) {
+ ScopedServiceWorkerCodeCacheForTest scoped_feature(true);
MockGeneratedCodeCache mock_disk_cache;
// Equivalent to service worker calling
@@ -198,6 +219,7 @@
TEST(
CachedMetadataHandlerTest,
DoesNotSendMetadataToPlatformWhenFetchedViaServiceWorkerWithDifferentURLCacheResponse) {
+ ScopedServiceWorkerCodeCacheForTest scoped_feature(true);
MockGeneratedCodeCache mock_disk_cache;
// Equivalent to service worker calling
@@ -213,5 +235,23 @@
EXPECT_EQ(0u, mock_disk_cache.CacheStorageCachedURLs().size());
}
+TEST(CachedMetadataHandlerTest,
+ ShouldUseIsolatedCodeCacheRespectsServiceWorkerCodeCacheFlag) {
+ ResourceResponse response(CreateTestResourceResponse());
+ response.SetWasFetchedViaServiceWorker(true);
+ response.SetUrlListViaServiceWorker({response.CurrentRequestUrl()});
+
+ {
+ ScopedServiceWorkerCodeCacheForTest scoped_feature(false);
+ EXPECT_FALSE(ShouldUseIsolatedCodeCache(
+ mojom::blink::RequestContextType::SCRIPT, response));
+ }
+ {
+ ScopedServiceWorkerCodeCacheForTest scoped_feature(true);
+ EXPECT_TRUE(ShouldUseIsolatedCodeCache(
+ mojom::blink::RequestContextType::SCRIPT, response));
+ }
+}
+
} // namespace
} // namespace blink