mirror of
https://github.com/morluto/rea
synced 2026-10-26 14:25:49 -04:00
e9fc8fb30c
* fix(javascript): preserve literal percent runtime paths * fix(javascript): ignore resolve prefixes before the final anchor * fix(electron): retain application roots for loadFile declarations * fix(electron): resolve loadFile from enclosing application package * fix(electron): retain outer application root across package scopes * fix(electron): derive application ownership from inventoried packages * fix(electron): retain resolved package entrypoint ownership * fix(electron): preserve competing application ownership * fix(electron): retain invalid and omitted runtime ownership * fix(electron): preserve omitted module ownership and runtime paths * fix(electron): preserve proven roots before confining page paths * fix(electron): retain possible owners behind missing imports * fix(electron): distinguish absent imports and owned page candidates * fix(electron): keep unavailable JSON out of owner gaps * fix(electron): retain exact loader formats and default entry status * fix(electron): retain unavailable entrypoint ownership candidates * test(ghidra): preserve Windows Node probe prerequisites * test(ghidra): assert cancellation during profile shutdown * fix(electron): separate examined imports from frontend ownership * fix(electron): retain unavailable directory entrypoint owners * test(jeb): retain Linux ownership prerequisite in isolation * fix(javascript): retain unchecked loader ownership and literal main paths * fix(javascript): preserve runtime paths and call-site module aliases * fix(javascript): bound module alias traversal and preserve projections * fix(javascript): retain host module and nested artifact path boundaries * fix(javascript): preserve ESM and archive module loader provenance * test(javascript): distinguish unmapped containers from missing exports * fix: retain default module aliases and Electron builtin imports * fix: preserve host file URL and inward ASAR ownership * fix: preserve CommonJS file URL classification in CI fixtures * fix: retain bound module loaders and Windows entrypoint uncertainty * fix: retain ASAR uncertainty and invalidate changed Electron app roots * fix(javascript): retain ownership uncertainty across loader boundaries * fix(javascript): preserve loader sources and bound alias queries * fix(javascript): retain destructured loader sources * fix(javascript): preserve loader uncertainty at resolution boundaries * fix(javascript): preserve callable and package launch ownership * fix(javascript): preserve captured values across member reads * test(process): assert tagged filesystem cancellation failures * fix(javascript): preserve inventory bases and invocation read timing * fix(javascript): preserve ownership across indirect and unread loads * test(javascript): order fixture directory creation on Windows * test(javascript): share ordered filesystem fixture writer * fix(javascript): unify loader provenance and package validation * fix(javascript): preserve captured Node require loader values * fix(javascript): preserve loader invocation authority * fix(javascript): verify generic loader invocation authority * fix(javascript): preserve conditional loader method alternatives * fix(javascript): require proven factories for source association * fix(javascript): honor replaced Electron app path setters * fix(javascript): prove path and assignment source ownership * fix(javascript): retain native delegate eligibility through shared writes * fix(process): settle stale baseline errors after confirmed absence * fix(javascript): preserve assignment and path boundary evidence * fix(javascript): prove source-directory resolve anchors * fix: preserve application path provenance and portable schemas * fix(javascript): retain CommonJS exported setter effects * fix: isolate Linux identity observations and retain native module exports * fix(javascript): preserve published app and helper provenance * fix(javascript): normalize typed stores and native path fixtures
125 lines
3.5 KiB
TypeScript
125 lines
3.5 KiB
TypeScript
import { expect, it, vi } from "vitest";
|
|
|
|
import {
|
|
verifyNoTokenOwnedProcesses,
|
|
type ProcessIdentityObservation,
|
|
type ProcessOwnershipHost,
|
|
type ProcessTableEntry,
|
|
} from "./ProcessOwnership.js";
|
|
import { ProcessOwnershipEvidenceOwner } from "./ProcessOwnershipEvidence.js";
|
|
|
|
const row: ProcessTableEntry = {
|
|
pid: 200,
|
|
parentPid: 100,
|
|
processGroupId: 100,
|
|
state: "S",
|
|
command: "listed-before-native-exit",
|
|
};
|
|
|
|
const absent = (platform: "linux" | "darwin"): ProcessIdentityObservation => ({
|
|
state: "absent",
|
|
reason:
|
|
platform === "linux"
|
|
? "not-found-in-caller-pid-namespace"
|
|
: "not-in-snapshot",
|
|
});
|
|
const unavailable: ProcessIdentityObservation = {
|
|
state: "unavailable",
|
|
reason: "native identity could not be read",
|
|
};
|
|
|
|
const fixture = (
|
|
platform: "linux" | "darwin",
|
|
observe: () => ProcessIdentityObservation,
|
|
) => {
|
|
const evidenceOwner = new ProcessOwnershipEvidenceOwner();
|
|
const signalGroup = vi.fn();
|
|
let listed = true;
|
|
const host: ProcessOwnershipHost = {
|
|
platform,
|
|
listProcesses: async () => (listed ? [row] : []),
|
|
environment: async () => ({}),
|
|
runTokens: async (entries) =>
|
|
new Map(
|
|
entries.map(({ pid }) => [
|
|
pid,
|
|
{ state: "readable", runId: undefined } as const,
|
|
]),
|
|
),
|
|
processIdentities: async (entries) =>
|
|
new Map(entries.map(({ pid }) => [pid, observe()])),
|
|
signalGroup,
|
|
};
|
|
return {
|
|
evidenceOwner,
|
|
signalGroup,
|
|
omitRow: () => {
|
|
listed = false;
|
|
},
|
|
verify: (identity: string | null) =>
|
|
verifyNoTokenOwnedProcesses(
|
|
"run-token",
|
|
host,
|
|
[{ pid: row.pid, identity }],
|
|
{ leaderPid: 100, processGroupId: 100, evidenceOwner },
|
|
),
|
|
};
|
|
};
|
|
|
|
it.each(
|
|
(["linux", "darwin"] as const).flatMap((platform) =>
|
|
(["old-start", null] as const).flatMap((baseline) =>
|
|
(["unavailable", "absent"] as const).map((first) => ({
|
|
platform,
|
|
baseline,
|
|
first,
|
|
})),
|
|
),
|
|
),
|
|
)(
|
|
"settles baseline $baseline after $first becomes native absence on $platform",
|
|
async ({ platform, baseline, first }) => {
|
|
let reads = 0;
|
|
const owned = fixture(platform, () =>
|
|
++reads === 1 && first === "unavailable" ? unavailable : absent(platform),
|
|
);
|
|
await expect(owned.verify(baseline)).resolves.toEqual({
|
|
cleaned: true,
|
|
signaled: false,
|
|
});
|
|
expect(owned.evidenceOwner.candidates).toEqual([]);
|
|
expect(owned.signalGroup).not.toHaveBeenCalled();
|
|
},
|
|
);
|
|
|
|
it.each(["linux", "darwin"] as const)(
|
|
"retains an unavailable generation after process-table omission on %s",
|
|
async (platform) => {
|
|
const owned = fixture(platform, () => unavailable);
|
|
const expected = {
|
|
cleaned: false,
|
|
reason: "process identity could not be revalidated",
|
|
failures: [
|
|
expect.objectContaining({
|
|
pid: row.pid,
|
|
reason: "process-identity-unavailable",
|
|
}),
|
|
],
|
|
};
|
|
await expect(owned.verify(null)).resolves.toMatchObject(expected);
|
|
expect(owned.evidenceOwner.candidates).toEqual([
|
|
expect.objectContaining({
|
|
pid: row.pid,
|
|
applicability: "identity-unresolved",
|
|
}),
|
|
]);
|
|
owned.omitRow();
|
|
await expect(owned.verify(null)).resolves.toMatchObject(expected);
|
|
expect(owned.evidenceOwner.candidates).toEqual([
|
|
expect.objectContaining({ pid: row.pid }),
|
|
]);
|
|
expect(owned.evidenceOwner.coverage.retainedOnlyPids).toBe(1);
|
|
expect(owned.signalGroup).not.toHaveBeenCalled();
|
|
},
|
|
);
|