From 4744674e933ebbd294878b60c93732500fd4217a Mon Sep 17 00:00:00 2001 From: Shelley Vohr Date: Mon, 29 Aug 2022 14:53:24 +0200 Subject: [PATCH] fix: crash when switching origins with emulation settings set (#35466) --- patches/chromium/.patches | 1 + ...ler_update_functions_to_early_return.patch | 45 +++++++++++++++++++ spec/api-web-contents-spec.ts | 30 +++++++++++++ 3 files changed, 76 insertions(+) create mode 100644 patches/chromium/fix_revert_emulationhandler_update_functions_to_early_return.patch diff --git a/patches/chromium/.patches b/patches/chromium/.patches index 485f18915fba..d53c82faf37f 100644 --- a/patches/chromium/.patches +++ b/patches/chromium/.patches @@ -117,3 +117,4 @@ add_maximized_parameter_to_linuxui_getwindowframeprovider.patch revert_spellcheck_fully_launch_spell_check_delayed_initialization.patch add_electron_deps_to_license_credits_file.patch feat_add_set_can_resize_mutator.patch +fix_revert_emulationhandler_update_functions_to_early_return.patch diff --git a/patches/chromium/fix_revert_emulationhandler_update_functions_to_early_return.patch b/patches/chromium/fix_revert_emulationhandler_update_functions_to_early_return.patch new file mode 100644 index 000000000000..7a34a6850465 --- /dev/null +++ b/patches/chromium/fix_revert_emulationhandler_update_functions_to_early_return.patch @@ -0,0 +1,45 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Shelley Vohr +Date: Fri, 26 Aug 2022 11:24:27 +0200 +Subject: fix: revert EmulationHandler update functions to early return + +Our debugger class (a subclass of ontent::DevToolsAgentHostClient) isn't +aware of those changes unless we hook RenderFrameHostChanged. If we +don't do this, some navigation lifecycle events +{loadingFinished, dataReceived} emitted by the renderer are lost. We +disconnect and reconnect the webcontents to the DevToolsAgentHost to +prevent this from happening. + +As of https://chromium-review.googlesource.com/c/chromium/src/+/3758294 +this results in a DCHECK, since DevToolsAgentHost::DisconnectWebContents +results in a call to UpdateDeviceEmulationState and host_ is nullptr. To +fix this, we revert those state update calls to early returns. + +Upstreamed at https://chromium-review.googlesource.com/c/chromium/src/+/3856525 + +diff --git a/content/browser/devtools/protocol/emulation_handler.cc b/content/browser/devtools/protocol/emulation_handler.cc +index 84736afeb21d1deec0f4032ef6f3304075d8fffb..d023bb7b5a34c5c055d3d7cc5dc3e04ef43bcc3b 100644 +--- a/content/browser/devtools/protocol/emulation_handler.cc ++++ b/content/browser/devtools/protocol/emulation_handler.cc +@@ -565,7 +565,9 @@ WebContentsImpl* EmulationHandler::GetWebContents() { + } + + void EmulationHandler::UpdateTouchEventEmulationState() { +- DCHECK(host_); ++ if (!host_) ++ return; ++ + // We only have a single TouchEmulator for all frames, so let the main frame's + // EmulationHandler enable/disable it. + DCHECK(!host_->GetParentOrOuterDocument()); +@@ -585,7 +587,9 @@ void EmulationHandler::UpdateTouchEventEmulationState() { + } + + void EmulationHandler::UpdateDeviceEmulationState() { +- DCHECK(host_); ++ if (!host_) ++ return; ++ + // Device emulation only happens on the outermost main frame. + DCHECK(!host_->GetParentOrOuterDocument()); + diff --git a/spec/api-web-contents-spec.ts b/spec/api-web-contents-spec.ts index f64170592822..3ceb081c76c9 100644 --- a/spec/api-web-contents-spec.ts +++ b/spec/api-web-contents-spec.ts @@ -326,6 +326,7 @@ describe('webContents module', () => { describe('loadURL() promise API', () => { let w: BrowserWindow; + beforeEach(async () => { w = new BrowserWindow({ show: false }); }); @@ -357,6 +358,35 @@ describe('webContents module', () => { .and.have.property('code', 'ERR_FAILED'); }); + it('does not crash when loading a new URL with emulation settings set', async () => { + const setEmulation = async () => { + if (w.webContents) { + w.webContents.debugger.attach('1.3'); + + const deviceMetrics = { + width: 700, + height: 600, + deviceScaleFactor: 2, + mobile: true, + dontSetVisibleSize: true + }; + await w.webContents.debugger.sendCommand( + 'Emulation.setDeviceMetricsOverride', + deviceMetrics + ); + } + }; + + try { + await w.loadURL(`file://${fixturesPath}/pages/blank.html`); + await setEmulation(); + await w.loadURL('data:text/html,

HELLO

'); + await setEmulation(); + } catch (e) { + expect((e as Error).message).to.match(/Debugger is already attached to the target/); + } + }); + it('sets appropriate error information on rejection', async () => { let err: any; try {