New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: lost window.opener after cross-origin navigation #18173
fix: lost window.opener after cross-origin navigation #18173
Conversation
failed on all platforms, so i believe it's a regression from this pr |
Oddly, it looks like it makes the test-case about temporary zoom fail :/ My feeling is that Looking into |
Given
So the tests relying on What should I do? Update them or tweak so that we force a different site instance when switching between |
I would say that the second option would probably be optimal for the purposes of this PR: to update tests to reflect the behavior your PR is designed to create |
@codebytere I'm not sure to understand your answer: you seem to recommend option 2 with the arguments of option 1 😀
After some thought, I lean towards option 1 because:
But I'd like to get the opinion of @deepak1556 and @ppontes (who worked on the subject and on the concerned tests) beforehand. 🙏 |
Whoops poor communication on my part: I intended option 1 i'll also defer to @deepak1556 and @ppontes though 🙇♀ |
Yeah the file scheme behavior difference we have from chrome is for legacy reasons, For fixing the test, yes option 1 is the right route. But I also want to decide on the |
As long as the renderer process is still restarted for navigations, I'm good with either way, otherwise it would be a breaking change. |
OK, I updated the failing test to test (more) real cross-origin navigations. However:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After testing the change, I think it is breaking the purpose of frame_host_manager.patch
, which is to force restarting renderer process for every navigation.
Most of the native Node.js modules can not be reloaded in the same process, they would just crash if you do so. So in Electron we have to force restarting renderer process for every navigation, otherwise any app using native modules would crash after navigation.
We implement this behavior by force creating a new site instance after doing navigations. And you can test whether this behavior is broken by printing process.pid
in devtools, and refresh to see whether it changes.
For #18032 we should probably find another way to fix it instead of changing the behavior of force creating new site instances, in Electron window.opener
is implemented with JS in lib/renderer/window-setup.ts
so it should be possible to fix it JS.
If the only solution is to change the behavior of force creating new site instances, we should introduce a new option for it instead of changing the default behavior.
FWIW this doesn't work with |
@@ -50,7 +50,7 @@ index 2314c6d1d29ebc61d5156644617e9eb088df5d43..9c75367a173b836027b3b7628b49b363 | |||
+ overriden_site_instance = | |||
+ candidate_site_instance | |||
+ ? candidate_site_instance | |||
+ : SiteInstance::CreateForURL(browser_context, | |||
+ : current_site_instance->GetRelatedSiteInstance( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm afraid that the fix to this problem is not this simple. As @zcbenz has already mentioned, we need to force the renderer process to restart upon navigating, to properly restart Node. This is the reason Electron is forcing an independent site instance in this case. #15821 fixed the window.opener problem for sandboxed renderers only, where Node is disabled and therefore there is no need to restart the process. I agree with @MarshallOfSound in that we should find a way to move towards the Chromium process model while properly restarting Node without forcing full process restarts.
@zcbenz oh ok I see it now: indeed it does break the purpose of Actually, I was originally looking for an equivalent of I +1 @MarshallOfSound opinion for the JS based implementation of For anyone (maybe me) willing to dig the subject of safely destruct/cleanup node environments, what are the relevant issues/code bytes one can look into? I had the feeling that @MarshallOfSound made some good progress with #16425, didn’t you? |
@alexstrat, thanks for looking into this!
With this approach we can end up with multiple site instances for the same site as part of the same browsing instance. Please ensure that this doesn't fail Chromium's expectations. |
I implemented the Regarding @ppontes 's remark, I'm still unsure of the consequences of having multiple site instances for the same site as part of the same browsing instance — except that it distances us from the 1 process-per-site model, from which we are already far anyway. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@alexstrat, please reset the changes introduced in the last commit to unrelated patch files.
The code seems logical but while testing your branch I bumped into the fact that preload scripts are no longer executed when opening x-site popups from an non-sandboxed renderer with nativeWindowOpen === true
. Can you please check this on your side?
Thanks for your time! Regarding the changes to unrelated patch files, I have had a discussion on the Electron's Slack with @nornagon about this who advised me to keep them 🤷♂️:
Happy to remove it anyway! LMK Regarding preload scripts non-execution in child windows with However, the intention of #15213 was to make sure we don't have several node integrations in a single render process. Given the fact that cross-site navigation creates a new render process, we could implement this intention differently. Note you can make sure preload-scripts are executed in child-windows with |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wasn't aware of such roller-bot issue, please then disregard my request to reset the changes.
Regarding the preload scripts, I understand your explanation but I'm a bit confused that nodeIntegration
being disabled in child windows means preload scripts not running for those child windows, as that is not the case when nodeIntegration
is disabled for a root window - the preload still runs and can do useful stuff even though require is then unavailable in the main world. Also, in sandbox renderers, nativeWindowOpen is implied true, nodeIntegration is implied false and the preload scripts are executed. But this seems to be another discussion. Approving from my side but still requesting a review from @deepak1556 who's knowledgeable in this area.
I have tried the new change but it still breaks the policy that navigations should restart the renderer process. It can be tested by open a process monitor and the reload the default app, and the PID should change for every reload. This would be a breaking change if the policy is changed. Using Atom and VS Code as example, currently you can reload the window and everything would still work, with this change the app would crash after reloading, because they are using native modules. We should of course find a better way than always reloading the renderer process, but before we get a better solution we have to stick to current way to ensure apps can work correctly. |
@zcbenz I had understood these requirements and their implications and I was sure I made the necessary, so I was surprised and sorry to see that it does not work on your side. 😔 However, I tested with You can verify that my changes have no impact when |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry I didn't notice the sandbox
option, things work as expected after removing it!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So here's my concern if I'm reading this thread correctly two things are true after this PR.
window.opener
is not null- We are still restarting / getting a new renderer for navigations
This means we have somehow made cross-process bi-directional synchronous communication which is the definition of how deadlocks happen. I'd argue that for the benefit of all users we shouldn't be letting them do that. E.g. We only allow synchronous IPC in one direction in our ipc
module, we shouldn't allow it here.
Rebase ✅ |
a9bc966
to
cfe18bc
Compare
@MarshallOfSound @deepak1556 can one of you merge this PR and start a backport, please? |
Using `GetRelatedSiteInstance` will keep the relation (same browsing instance) between the current and the new site instance.
The fact that, now, we always have an opener for opened windows diables note integration in opened windows, except if `nodeIntegrationInSubFrames` is enabled.
…s-origin navigation" This reverts commit 0a7537f.
cfe18bc
to
6b2f4ca
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
macOS failure is due to the PR coming from a fork. Approving for master 👍
Release Notes Persisted
|
A maintainer has manually backported this PR to "5-0-x", please check out #18614 |
A maintainer has manually backported this PR to "6-0-x", please check out #18624 |
Backports for 5-0-x and 6-0-x are ready to review and merge. |
@MarshallOfSound @deepak1556 could you approve the backport for electron 5 #18614 so that the fix gets released soon, please? |
Fixes #18032
Description of Change
With #15821, on cross-origin navigation, we use
SiteInstance::CreateForURL
to get the appropriateSiteInstance
but in a new BrowsingInstance. It means we lose the relationship (by browsing instance) between the current and the newSiteInstance
, and thus thewindow.opener
is null in the opened window.In this PR, I suggest usingGetRelatedSiteInstance
to keep the relationship.In this PR, I introduce and use a
SiteInstance::CreateRelatedSiteInstance
that keeps the browsing instance relationship.cc @ppontes @deepak1556
Checklist
npm test
passeschanged oraddedRelease Notes
Notes: Fixed
window.opener
null after cross-origin navigation