Bug: Uncaught exception on Download.launch for object URLs
Status: VERIFIED
Priority: --
Resolution: FIXED
Created: 2022-05-26 09:29:34+00:00
Resolved: 2022-06-08 12:29:58+00:00

Here's an error I'm seeing in the browser console since bug 1722050:
```
TypeError: URL constructor: null is not a valid URL. EnterprisePoliciesParent.jsm:440:20
    isExemptExecutableExtension resource://gre/modules/EnterprisePoliciesParent.jsm:440
    launchDownload resource://gre/modules/DownloadIntegration.jsm:740
    launch resource://gre/modules/DownloadCore.jsm:820
    _succeed resource://gre/modules/DownloadCore.jsm:616
    InterpretGeneratorResume self-hosted:1469
    AsyncFunctionNext self-hosted:679
    (Async: async)
    D_start resource://gre/modules/DownloadCore.jsm:591
    InterpretGeneratorResume self-hosted:1469
    AsyncFunctionNext self-hosted:679
    (Async: async)
    D_start resource://gre/modules/DownloadCore.jsm:595
    _nsITransferInitInternal resource://gre/modules/DownloadLegacy.jsm:431
    (Async: promise callback)
    _nsITransferInitInternal resource://gre/modules/DownloadLegacy.jsm:424
    initWithBrowsingContext resource://gre/modules/DownloadLegacy.jsm:316
    onOK resource://gre/modules/HelperAppDlg.jsm:1101
    handleEvent resource://gre/modules/HelperAppDlg.jsm:1148
    _fireButtonEvent chrome://global/content/elements/dialog.js:495
    _doButtonCommand chrome://global/content/elements/dialog.js:474
    _handleButtonCommand chrome://global/content/elements/dialog.js:468
    _handleButtonCommand self-hosted:1162
    (Async: EventListener.handleEvent)
    _configureButtons chrome://global/content/elements/dialog.js:369
    connectedCallback chrome://global/content/elements/dialog.js:163
    <anonymous> chrome://global/content/customElements.js:217
    (Async: EventListener.handleEvent)
    <anonymous> chrome://global/content/customElements.js:209
    <anonymous> chrome://global/content/customElements.js:861
    observe resource://gre/modules/CustomElementsListener.jsm:26
```
So what seems to be happening is I'm downloading from a blob URL, for example, and [DownloadIntegration.launchDownload](https://searchfox.org/mozilla-central/rev/301e9545863b14ff85aa110fabd4274da4593f9d/toolkit/components/downloads/DownloadIntegration.jsm#738-746) is trying to create a new URL object from the source URL and pass url.origin to [isExemptExecutableExtension](https://searchfox.org/mozilla-central/rev/301e9545863b14ff85aa110fabd4274da4593f9d/toolkit/components/enterprisepolicies/EnterprisePoliciesParent.jsm#440).

The instantiation of the URL object and the invocation of `isExemptExecutableExtension` are wrapped in a try block, but the exception happens within `isExemptExecutableExtension`, when `hostname` is defined.

A simple fix is to check that `origin` exists above the `hostname` declaration, or even to check that `url.origin` exists before invoking `isExemptExecutableExtension`. But it would be safer to just call `new URL(origin)` in a try block, since it's conceivable that future code might pass origins that fail for other reasons. Currently I only know of cases where `origin` is null or undefined, but I guess it's possible that some caller might pass invalid characters or something. That pattern also seems pretty common in the Firefox code base, so that seems best.

### STR
1. Try downloading a file from an object URL, e.g., an icon [from here](https://fonts.google.com/icons?selected=Material+Icons)
2. Once it's finished, check the browser console

### Expected
No errors logged in console

### Actual
There's an unhandled exception, the stack trace is pasted above