8000 refactor: use separate ipc-renderer-internal / ipc-main-internal APIs for Electron internals by miniak · Pull Request #13940 · electron/electron · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

refactor: use separate ipc-renderer-internal / ipc-main-internal APIs for Electron internals #13940

8000 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

Merged
merged 1 commit into from
Oct 6, 2018

Conversation

miniak
Copy link
Contributor
@miniak miniak commented Aug 5, 2018
  • internal implementation details (like the remote module) are no longer using the public ipcRenderer / ipcMain modules
  • this will allow application message filtering in the main process without having the consider internal messages
  • ipcRenderer.removeAllListeners() is now safe to call
  • ipcMain.removeAllListeners() is now safe to call
  • less leakage of implementation details (EventEmitter allows access to all listeners)
Checklist

Notes: Public IPC channel (ipcRenderer / ipcMain) is no longer used to implement Electron internals (remote module for example)

@miniak miniak requested a review from a team August 5, 2018 11:36
}

// Do not throw exception when channel name is "error".
emitter.on('error', () => {})
Copy link
Contributor Author
@miniak miniak Aug 5, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

anybody knows why do we need this piece of code?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@miniak Node.JS throws an unhandled exception if an event emitter emits error with no handlers. Having this handler stops that occuring. We definitely still need it 👍

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@MarshallOfSound restored

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@MarshallOfSound ipcRenderer does not handle the error event compared to ipcMain

@miniak miniak force-pushed the miniak/internal-ipc branch from c8b07e9 t 8000 o c357434 Compare August 5, 2018 12:13
@MarshallOfSound MarshallOfSound added the semver/major incompatible API changes label Aug 5, 2018
@MarshallOfSound
Copy link
Member

Labeling as breaking change as some users may be relying on Electron internals (sending / receiving Electron IPC events)

@miniak
Copy link
Contributor Author
miniak commented Aug 5, 2018

@MarshallOfSound do you agree with the idea of separating the IPC channels for internal / public use?

@MarshallOfSound
Copy link
Member

@miniak Yeah 100%, future iterations of this could completely hide the internal channel from developers but this is a great move 👍

describe('ipcRenderer.on', () => {
it('is not used for internals', (done) => {
w = new BrowserWindow({ show: false })
w.webContents.once('did-finish-load', async () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

w.loadURL('about:blank')
await emittedOnce(w.webContents, 'did-finish-load')
<...>

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let appProcess = cp.spawn(electronPath, [appPath])

appProcess.stdout.on('data', (data) => { output += data })
appProcess.stdout.on('end', () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably it's easier to

appProcess.stdout.on('data', (data) => { output += data })
await emittedOnce(appProcess.stdout, 'end')
<...>

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

throw new TypeError('First argument has to be webContentsId')
}

ipcRenderer.send('ELECTRON_BROWSER_SEND_TO', true, false, webContentsId, channel, ...args)
Copy link
Contributor
@alexeykuzmin alexeykuzmin Aug 6, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please add inline comments for what all these true, false mean?

doStuff(/* shouldWriteMoreCode */ true, /* willAddMoreComments */ false, ...)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@alexeykuzmin I've used constants to name the arguments instead, is that ok?

}

WebContents.prototype._sendInternal = function (channel, ...args) {
if (channel == null) throw new Error('Missing required channel argument')
Copy link
Contributor
@alexeykuzmin alexeykuzmin Aug 6, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should check the first arg type instead of comparing it with null and undefined?

if (typeof channel != 'string')

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@alexeykuzmin
Copy link
Contributor

@MarshallOfSound Why do you think it's a breaking change?
As far as I understand there shouldn't be any noticeable changes from the users' perspective.

@MarshallOfSound
Copy link
Member

@alexeykuzmin Some people will be using electron internal IPC to do things, for instance we have an app that sends an internal IPC message delibrately

@ckerr
Copy link
Member
ckerr commented Aug 9, 2018

re: whether or not this deserves the semver/nonbreaking-feature label...

That label is used as a reminder to not backport, so IMO this is really a discussion of whether or not to include in 3.0.0.

This diff is huge and we're late in the beta cycle and this isn't a blocker issue.

It's safer to leave this targeted for 4.0.0.

@alexeykuzmin
Copy link
Contributor
alexeykuzmin commented Aug 10, 2018

@ckerr I agree that big changes shouldn't be merged into release branches if they cannot be thoroughly tested before a release should go stable.
My question was related to a "backportability" of this change, but not strictly about it.

UPD We probably just need a new label "do-not-backport" to prevent backports.
Using "semver/breaking-change" for this is an ugly workaround and just doesn't make much sense.

@alexeykuzmin
Copy link
Contributor

Some people will be using electron internal IPC to do things

Some people shouldn't be doing that.

What's the point of having public API and private implementation, if people keep using whatever they want?
If somebody uses an undocumented or private API and the API breaks it's their problem, not a product's fault. Asking maintainers to roll back the change, or keep supporting the old behaviour just creates additional cost for the product's maintenance and reduces amount of resources available to fix bugs or implement new features for "good users".

@ckerr
Copy link
Member
ckerr commented Aug 10, 2018

We probably just need a new label "do-not-backport" to prevent backports. Using "semver/breaking-change" for this is an ugly workaround and just doesn't make much sense.

Hmm actually I like the semver/* tags for this because they explain why backporting shouldn't be done. do-not-backport only says to not do it.

I agree it doesn't cover this case though, so maybe a new label is needed in addition to the existing semver/* labels

@MarshallOfSound
Copy link
Member

Some people shouldn't be doing that.

Quite possibly.

If somebody uses an undocumented or private API and the API breaks it's their problem, not a product's fault. Asking maintainers to roll back the change, or keep supporting the old behaviour just creates additional cost for the product's maintenance and reduces amount of resources available to fix bugs or implement new features for "good users".

100% agree, that's why I'm advocating this goes into a major release, not that it goes through the "deprecation" cycle. I'm just pointing out that this can and will have side effects. The key example being people who use the events, but also people's tests. If someone is checking the amount of IPC listeners this will implicitly be broken now because the number will be slightly different.

I'm on board with this going out, but only in a major.

@miniak miniak force-pushed the miniak/internal-ipc branch 3 times, most recently from 43e7e1e to 28503df Compare August 14, 2018 22:48
@miniak miniak changed the title [wip] security: use separate ipc-renderer-internal / ipc-main-internal APIs for Electron internals[ [wip] security: use separate ipc-renderer-internal / ipc-main-internal APIs for Electron internals Aug 14, 2018
@alexeykuzmin
Copy link
Contributor

@MarshallOfSound Can you please review this again?

@miniak miniak changed the title [wip] security: use separate ipc-renderer-internal / ipc-main-internal APIs for Electron internals security: use separate ipc-renderer-internal / ipc-main-internal APIs for Electron internals Aug 17, 2018
@miniak miniak force-pushed the miniak/internal-ipc branch 3 times, most recently from b36dccd to e3e28ce Compare August 21, 2018 22:36
@MarshallOfSound
Copy link
Member

@miniak This is coated in conflicts, if you get those cleaned up I'm down to land this 👍

@miniak miniak force-pushed the miniak/internal-ipc branch 2 times, most recently from 4a9e37b to e82796c Compare August 24, 2018 22:04
@miniak miniak force-pushed the miniak/internal-ipc branch 2 times, most recently from 56da12d to e5a3a03 Compare September 22, 2018 14:31
@MarshallOfSound
Copy link
Member

@miniak I've tried to write my enforcement tests but it literally makes the electron test suite take ~10-15 minutes extra (which is pretty silly). I'm down to land this as-is

@miniak miniak force-pushed the miniak/internal-ipc branch 7 times, most recently from 923484f to c00acaf Compare October 2, 2018 09:28
@miniak
Copy link
Contributor Author
miniak commented Oct 2, 2018

@MarshallOfSound rebased and conflicts resolved on the latest master.

@alexeykuzmin
Copy link
Contributor

@miniak linux tests fail with a crash.

@miniak
Copy link
Contributor Author
miniak commented Oct 3, 2018

@alexeykuzmin the crash seems to be completely unrelated to this change.

@miniak
Copy link
Contributor Author
miniak commented Oct 3, 2018
[820:1003/194021.048097:ERROR:service_manager_context.cc(258)] Attempting to run unsupported native service: /home/builduser/project/src/out/Default/content_gpu.service
[820:1003/194021.092938:ERROR:service_manager_context.cc(258)] Attempting to run unsupported native service: /home/builduser/project/src/out/Default/content_gpu.service
[820:1003/194021.095075:ERROR:gpu_process_host.cc(467)] !GpuDataManagerImpl::GpuProcessStartAllowed()
[820:1003/194021.095624:ERROR:gpu_process_host.cc(467)] !GpuDataManagerImpl::GpuProcessStartAllowed()
[820:1003/194021.095649:ERROR:browser_gpu_channel_host_factory.cc(119)] Failed to launch GPU process.
[820:1003/194021.095738:ERROR:gpu_process_transport_factory.cc(1027)] Lost UI shared context.
[820:1003/194021.277510:ERROR:gpu_process_host.cc(467)] !GpuDataManagerImpl::GpuProcessStartAllowed()
[820:1003/194023.339759:FATAL:thread_restrictions.cc(29)] Check failed: !g_blocking_disallowed.Get().Get(). Function marked as blocking was called from a scope that disallows blocking! If this task is running inside the TaskScheduler, it needs to have MayBlock() in its TaskTraits. Otherwise, consider making this blocking work asynchronous or, as a last resort, you may use ScopedAllowBlocking in a narrow scope.
#0 0x0000039d8923 <unknown>
#1 0x0000039fdfe0 <unknown>
#2 0x000003a75e56 <unknown>
#3 0x000003a31302 <unknown>
#4 0x000003a312b9 <unknown>
#5 0x0000039fbdc1 <unknown>
#6 0x000003969c6b <unknown>
#7 0x00000396a5b6 <unknown>
#8 0x000003967d11 <unknown>
#9 0x0000051c40af <unknown>
#10 0x000002b9f0ba <unknown>
#11 0x000002b4b70f <unknown>
#12 0x000002b49828 <unknown>
#13 0x000002b4928d <unknown>
#14 0x3ba03b584384 <unknown>

@miniak miniak force-pushed the miniak/internal-ipc branch from c00acaf to fdd6fa1 Compare October 3, 2018 21:02
@MarshallOfSound
Copy link
Member

cc @nitsakh ^^

@miniak miniak force-pushed the miniak/internal-ipc branch 3 times, most recently from 4997929 to cf5347e Compare October 5, 2018 06:12
@miniak miniak force-pushed the miniak/internal-ipc branch from cf5347e to 77eb01e Compare October 5, 2018 18:48
@MarshallOfSound MarshallOfSound merged commit b50f86e into master Oct 6, 2018
@release-clerk
Copy link
release-clerk bot commented Oct 6, 2018

Release Notes Persisted

Public IPC channel (ipcRenderer / ipcMain) is no longer used to implement Electron internals (remote module for example)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
semver/major incompatible API changes
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants
0