Open Bug 1817152 Opened 2 years ago Updated 4 months ago

`Worker()` fails after `self.close()`

Categories

(Core :: DOM: Workers, defect, P3)

Firefox 110
defect

Tracking

()

People

(Reporter: daxpedda, Unassigned)

Details

(Whiteboard: dom-lws-bugdash-triage)

User Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/110.0

Steps to reproduce:

Trying to call the Worker constructor after calling DedicatedWorkerGlobalScope.close().

root:

new Worker('worker.js');

worker.js:

console.log('Hello from worker!');
self.close();

new Worker('worker.js'); // Fails here.

Actual results:

Constructing the nested worker after calling self.close() will throw an exception:

NetworkError: Worker constructor: Failed to load worker script at worker.js (nsresult = 0x80004005)

Expected results:

I'm actually not sure if this is intended or not, but other browsers, like Chrome, just do nothing instead.

I've also tried out the following:

  • Used the module type in the constructor.
  • Used a different URL in the nested constructor.
  • Used Blobs in the nested constructor.

All fail with the exact same message.

The Bugbug bot thinks this bug should belong to the 'Core::JavaScript Engine' component, and is moving the bug to that component. Please correct in case you think the bot is wrong.

Component: Untriaged → JavaScript Engine
Product: Firefox → Core
Component: JavaScript Engine → DOM: Service Workers
Flags: needinfo?(jmarshall)
Flags: needinfo?(echuang)
Flags: needinfo?(bugmail)

An interesting edge case, thanks for reporting this!

The reason for this error path is:

Note that slightly interestingly, we will have successfully acquired a StrongWorkerRef for the parent in WorkerPrivate::Constructor, but that's because the ref has the default threshold of Canceling, rather than Closing, our current status.

I think we probably should not be throwing a NetworkError here per the current spec's Worker constructor algorithm, but the spec does allow us to throw a SecurityError in step 1, and I think that's probably the right thing for us to do if we change our behavior here prior to spec changes happening relative to self.close().

There's been some discussion of making workers post self.close() behave more like detached iframes, so it may be worth considering doing the spec work to change what happens there rather than changing our behavior here to align to the current letter of the spec which is arguably not the spirit of the spec. In general, letting anything happen after self.close() introduces surface area that's primarily only of reasonable use to security researchers. (Like, one could argue that the spec allows code to do self.close() then go into an infinite loop and let a spawned worker do a bunch of things that are observable by other means like using BroadcastChannel, but it's quite reasonable in that case to say "don't call close() if you want your worker to be able to keep doing things.")

Severity: -- → S3
Flags: needinfo?(jmarshall)
Flags: needinfo?(echuang)
Flags: needinfo?(bugmail)
Priority: -- → P3

(This is only applicable to dedicated workers and shared workers, and not service workers, as there is no close() method on the ServiceWorkerGlobalScope.)

Component: DOM: Service Workers → DOM: Workers
Whiteboard: dom-lws-bugdash-triage
Status: UNCONFIRMED → NEW
Ever confirmed: true
You need to log in before you can comment on or make changes to this bug.