commit e784d5c2e5c52a287488f01fc1a2769dc99ae33c
parent 8dd3430b7a02680ea4bf368dfd3f1459135b3b85
Author: Harveer Singh <hsingh@mozilla.com>
Date: Tue, 25 Nov 2025 19:38:51 +0000
Bug 1999084: Handle and return error when a worker script length is over the threshold.r=edenchuang,dom-worker-reviewers
Differential Revision: https://phabricator.services.mozilla.com/D273311
Diffstat:
4 files changed, 22 insertions(+), 0 deletions(-)
diff --git a/dom/locales/en-US/chrome/dom/dom.properties b/dom/locales/en-US/chrome/dom/dom.properties
@@ -179,6 +179,7 @@ HittingMaxWorkersPerDomain2=A Worker could not be started immediately because ot
# LOCALIZATION NOTE: Do not translate "Application Cache API", "AppCache" and "ServiceWorker".
AppCacheWarning=The Application Cache API (AppCache) is deprecated and will be removed at a future date. Please consider using ServiceWorker for offline support.
# LOCALIZATION NOTE: Do not translate "Worker".
+WorkerScriptTooLargeError=The worker script is too large and cannot be loaded.
EmptyWorkerSourceWarning=Attempting to create a Worker from an empty source. This is probably unintentional.
NavigatorGetUserMediaWarning=navigator.mozGetUserMedia has been replaced by navigator.mediaDevices.getUserMedia
# LOCALIZATION NOTE: Do not translate "RTCPeerConnection", "getLocalStreams", "getRemoteStreams", "getSenders" or "getReceivers".
diff --git a/dom/serviceworkers/ServiceWorkerScriptCache.cpp b/dom/serviceworkers/ServiceWorkerScriptCache.cpp
@@ -894,6 +894,12 @@ CompareNetwork::OnStreamComplete(nsIStreamLoader* aLoader,
nsresult rv = NS_ERROR_FAILURE;
auto guard = MakeScopeExit([&] { NetworkFinish(rv); });
+ if (aLen > GetWorkerScriptMaxSizeInBytes()) {
+ rv = NS_ERROR_DOM_ABORT_ERR; // This will make sure an exception gets
+ // thrown to the global.
+ return NS_OK;
+ }
+
if (NS_WARN_IF(NS_FAILED(aStatus))) {
rv = (aStatus == NS_ERROR_REDIRECT_LOOP) ? NS_ERROR_DOM_SECURITY_ERR
: aStatus;
diff --git a/dom/workers/WorkerCommon.h b/dom/workers/WorkerCommon.h
@@ -8,6 +8,7 @@
#define mozilla_dom_workers_WorkerCommon_h
#include "js/TypeDecls.h"
+#include "nsString.h"
class nsPIDOMWindowInner;
@@ -61,6 +62,11 @@ bool IsWorkerDebuggerSandbox(JSObject* object);
void UpdateWorkersPlaybackState(const nsPIDOMWindowInner& aWindow,
bool aIsPlayingAudio);
+inline size_t GetWorkerScriptMaxSizeInBytes() {
+ // This is the max size that any of our worker scripts can be.
+ return nsString::LengthStorage::kMax;
+}
+
} // namespace mozilla::dom
#endif // mozilla_dom_workers_WorkerCommon_h
diff --git a/dom/workers/loader/NetworkLoadHandler.cpp b/dom/workers/loader/NetworkLoadHandler.cpp
@@ -68,6 +68,15 @@ nsresult NetworkLoadHandler::DataReceivedFromNetwork(nsIStreamLoader* aLoader,
const uint8_t* aString) {
AssertIsOnMainThread();
MOZ_ASSERT(!mRequestHandle->IsEmpty());
+
+ if (aStringLen > GetWorkerScriptMaxSizeInBytes()) {
+ Document* parentDoc = mWorkerRef->Private()->GetDocument();
+ nsContentUtils::ReportToConsole(nsIScriptError::errorFlag, "DOM"_ns,
+ parentDoc, nsContentUtils::eDOM_PROPERTIES,
+ "WorkerScriptTooLargeError");
+ return NS_ERROR_DOM_ABORT_ERR;
+ }
+
WorkerLoadContext* loadContext = mRequestHandle->GetContext();
if (!loadContext->mChannel) {