mirror of
https://github.com/morluto/rea.git
synced 2026-11-11 01:13:39 +00:00
fix(electron): keep literal IPC sends ambiguous beside unresolved handlers (#8120)
* fix(electron): keep literal IPC sends ambiguous beside unresolved handlers A main handler on an unresolved channel can receive any literal renderer send of a compatible mode, but pairing ignored it unless it had a scoped receiver. The send was then reported unpaired, or paired with another handler. Treat an unresolved-channel handler as a competitor that never pairs. The wrapper pass seeds only calls with a literal first argument, so it now records which invocations of a dynamic site it traced. The syntax finding gains `invocation_channels: "literal"` only when every invocation is a traced direct call of an unexported local function supplying a literal channel. Such a site is already represented by its per-invocation findings and does not compete. Fixes #8118 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(electron): keep guarded wrapper registrations competing in IPC pairing A guarded wrapper registration keeps its predicate on a call path and has no IPC finding. It still counted toward `invocation_channels: "literal"`, so pairing lost it: a send on that channel was reported unpaired, or paired uniquely with a direct handler. The enumerated site now carries these channels as `guarded_invocation_channels`, and each one competes for its own channel without pairing. Index each binding's direct call sites by appending in place. Spreading the earlier calls on every reference was quadratic in a file's call count. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
72039ecca9
commit
81378efb71
6 files changed
+317
-19
No files matched your search
@@ -68,14 +68,14 @@ export const createElectronIpcContext = (
|
||||
.filter(isPairableRendererTransmission)
|
||||
.map((transmission) => {
|
||||
const owner = owners.get(transmission.key);
|
||||
const channel = transmission.finding.channel;
|
||||
const matching =
|
||||
transmission.finding.channel === null
|
||||
channel === null
|
||||
? []
|
||||
: handlers.filter(
|
||||
(handler) =>
|
||||
(handler.finding.channel === transmission.finding.channel ||
|
||||
(handler.finding.receiver !== undefined &&
|
||||
handler.finding.channel === null)) &&
|
||||
(handler.finding.channel === channel ||
|
||||
mayReceiveChannel(handler, channel)) &&
|
||||
compatibleIpcModes(transmission.finding, handler.finding),
|
||||
);
|
||||
const candidates = matching.filter(
|
||||
@@ -94,14 +94,14 @@ export const createElectronIpcContext = (
|
||||
!coverageComplete &&
|
||||
owner != null &&
|
||||
candidates.length === 1 &&
|
||||
candidates[0]?.finding.receiver === undefined &&
|
||||
isExactIpcHandler(candidates[0]) &&
|
||||
!matching.some((handler) => owners.get(handler.key) == null)
|
||||
? (candidates[0] ?? null)
|
||||
: null,
|
||||
status:
|
||||
!uncertain &&
|
||||
candidates.length === 1 &&
|
||||
candidates[0]?.finding.receiver === undefined
|
||||
isExactIpcHandler(candidates[0])
|
||||
? "paired"
|
||||
: uncertain || matching.length > 0
|
||||
? "ambiguous"
|
||||
@@ -240,6 +240,27 @@ const isRendererTransmission = ({ finding }: ElectronIpcRecord): boolean =>
|
||||
const isPairableRendererTransmission = (record: ElectronIpcRecord): boolean =>
|
||||
isRendererTransmission(record) && record.finding.operation !== "send-to-host";
|
||||
|
||||
/**
|
||||
* An unresolved channel may receive any literal channel, so it competes without
|
||||
* ever pairing. A wrapper site whose invocations all supplied literal channels
|
||||
* is represented by their findings, except guarded invocations, which have none
|
||||
* and still compete for their own channels.
|
||||
*/
|
||||
const mayReceiveChannel = (
|
||||
{ finding }: ElectronIpcRecord,
|
||||
channel: string,
|
||||
): boolean =>
|
||||
finding.channel === null &&
|
||||
(finding.receiver !== undefined ||
|
||||
finding.invocation_channels !== "literal" ||
|
||||
finding.guarded_invocation_channels?.includes(channel) === true);
|
||||
|
||||
/** Only an ipcMain registration on the same literal channel can be paired. */
|
||||
const isExactIpcHandler = (handler: ElectronIpcRecord | undefined): boolean =>
|
||||
handler !== undefined &&
|
||||
handler.finding.receiver === undefined &&
|
||||
handler.finding.channel !== null;
|
||||
|
||||
const isMainHandler = ({ finding }: ElectronIpcRecord): boolean =>
|
||||
finding.side === "main" &&
|
||||
(finding.mode === "listen" || finding.mode === "handle");
|
||||
|
||||
Reference in new issue
Block a user