fix: crash when setWindowOpenHandler
callback throws (#34523)
* fix: crash when setWindowOpenHandler throws * refactor: throw as process uncaughtException event
This commit is contained in:
parent
8de5cdb426
commit
bed38e0985
2 changed files with 77 additions and 8 deletions
|
@ -482,6 +482,7 @@ WebContents.prototype._callWindowOpenHandler = function (event: Electron.Event,
|
|||
if (!this._windowOpenHandler) {
|
||||
return defaultResponse;
|
||||
}
|
||||
|
||||
const response = this._windowOpenHandler(details);
|
||||
|
||||
if (typeof response !== 'object') {
|
||||
|
@ -644,7 +645,15 @@ WebContents.prototype._init = function () {
|
|||
postBody,
|
||||
disposition
|
||||
};
|
||||
const result = this._callWindowOpenHandler(event, details);
|
||||
|
||||
let result;
|
||||
try {
|
||||
result = this._callWindowOpenHandler(event, details);
|
||||
} catch (err) {
|
||||
event.preventDefault();
|
||||
throw err;
|
||||
}
|
||||
|
||||
const options = result.browserWindowConstructorOptions;
|
||||
if (!event.defaultPrevented) {
|
||||
openGuestWindow({
|
||||
|
@ -675,7 +684,15 @@ WebContents.prototype._init = function () {
|
|||
referrer,
|
||||
postBody
|
||||
};
|
||||
const result = this._callWindowOpenHandler(event, details);
|
||||
|
||||
let result;
|
||||
try {
|
||||
result = this._callWindowOpenHandler(event, details);
|
||||
} catch (err) {
|
||||
event.preventDefault();
|
||||
throw err;
|
||||
}
|
||||
|
||||
windowOpenOutlivesOpenerOption = result.outlivesOpener;
|
||||
windowOpenOverriddenOptions = result.browserWindowConstructorOptions;
|
||||
if (!event.defaultPrevented) {
|
||||
|
|
|
@ -79,6 +79,58 @@ describe('webContents.setWindowOpenHandler', () => {
|
|||
|
||||
afterEach(closeAllWindows);
|
||||
|
||||
it('does not fire window creation events if the handler callback throws an error', (done) => {
|
||||
const error = new Error('oh no');
|
||||
const listeners = process.listeners('uncaughtException');
|
||||
process.removeAllListeners('uncaughtException');
|
||||
process.on('uncaughtException', (thrown) => {
|
||||
try {
|
||||
expect(thrown).to.equal(error);
|
||||
done();
|
||||
} catch (e) {
|
||||
done(e);
|
||||
} finally {
|
||||
process.removeAllListeners('uncaughtException');
|
||||
listeners.forEach((listener) => process.on('uncaughtException', listener));
|
||||
}
|
||||
});
|
||||
|
||||
browserWindow.webContents.on('new-window', () => {
|
||||
assert.fail('new-window should not be called with an overridden window.open');
|
||||
});
|
||||
|
||||
browserWindow.webContents.on('did-create-window', () => {
|
||||
assert.fail('did-create-window should not be called with an overridden window.open');
|
||||
});
|
||||
|
||||
browserWindow.webContents.executeJavaScript("window.open('about:blank', '', 'show=no') && true");
|
||||
|
||||
browserWindow.webContents.setWindowOpenHandler(() => {
|
||||
throw error;
|
||||
});
|
||||
});
|
||||
|
||||
it('does not fire window creation events if the handler callback returns a bad result', async () => {
|
||||
const bad = new Promise((resolve) => {
|
||||
browserWindow.webContents.setWindowOpenHandler(() => {
|
||||
setTimeout(resolve);
|
||||
return [1, 2, 3] as any;
|
||||
});
|
||||
});
|
||||
|
||||
browserWindow.webContents.on('new-window', () => {
|
||||
assert.fail('new-window should not be called with an overridden window.open');
|
||||
});
|
||||
|
||||
browserWindow.webContents.on('did-create-window', () => {
|
||||
assert.fail('did-create-window should not be called with an overridden window.open');
|
||||
});
|
||||
|
||||
browserWindow.webContents.executeJavaScript("window.open('about:blank', '', 'show=no') && true");
|
||||
|
||||
await bad;
|
||||
});
|
||||
|
||||
it('does not fire window creation events if an override returns action: deny', async () => {
|
||||
const denied = new Promise((resolve) => {
|
||||
browserWindow.webContents.setWindowOpenHandler(() => {
|
||||
|
@ -87,11 +139,11 @@ describe('webContents.setWindowOpenHandler', () => {
|
|||
});
|
||||
});
|
||||
browserWindow.webContents.on('new-window', () => {
|
||||
assert.fail('new-window should not to be called with an overridden window.open');
|
||||
assert.fail('new-window should not be called with an overridden window.open');
|
||||
});
|
||||
|
||||
browserWindow.webContents.on('did-create-window', () => {
|
||||
assert.fail('did-create-window should not to be called with an overridden window.open');
|
||||
assert.fail('did-create-window should not be called with an overridden window.open');
|
||||
});
|
||||
|
||||
browserWindow.webContents.executeJavaScript("window.open('about:blank', '', 'show=no') && true");
|
||||
|
@ -107,11 +159,11 @@ describe('webContents.setWindowOpenHandler', () => {
|
|||
});
|
||||
});
|
||||
browserWindow.webContents.on('new-window', () => {
|
||||
assert.fail('new-window should not to be called with an overridden window.open');
|
||||
assert.fail('new-window should not be called with an overridden window.open');
|
||||
});
|
||||
|
||||
browserWindow.webContents.on('did-create-window', () => {
|
||||
assert.fail('did-create-window should not to be called with an overridden window.open');
|
||||
assert.fail('did-create-window should not be called with an overridden window.open');
|
||||
});
|
||||
|
||||
await browserWindow.webContents.loadURL('data:text/html,<a target="_blank" href="http://example.com" style="display: block; width: 100%; height: 100%; position: fixed; left: 0; top: 0;">link</a>');
|
||||
|
@ -129,11 +181,11 @@ describe('webContents.setWindowOpenHandler', () => {
|
|||
});
|
||||
});
|
||||
browserWindow.webContents.on('new-window', () => {
|
||||
assert.fail('new-window should not to be called with an overridden window.open');
|
||||
assert.fail('new-window should not be called with an overridden window.open');
|
||||
});
|
||||
|
||||
browserWindow.webContents.on('did-create-window', () => {
|
||||
assert.fail('did-create-window should not to be called with an overridden window.open');
|
||||
assert.fail('did-create-window should not be called with an overridden window.open');
|
||||
});
|
||||
|
||||
await browserWindow.webContents.loadURL('data:text/html,<a href="http://example.com" style="display: block; width: 100%; height: 100%; position: fixed; left: 0; top: 0;">link</a>');
|
||||
|
|
Loading…
Reference in a new issue