Files
reverse-engineering-anything/src/desktop/LibraryPackageInventory.test.ts
T
morluto cb4e5cfbff feat(analysis): make resource budgets recoverable across CLI and MCP (#9706)
* refactor(analysis): centralize resource budgets and recovery facts

* feat(analysis): expose ASAR and Ghidra runtime admission controls

* feat(artifacts): expose reader admission and preserve limited recognition

* feat(javascript): expose recoverable semantic precision budgets

* feat(web): add recoverable source-map budgets and compact retained views

* feat(web): make historical capture decoding budgets recoverable

* fix(desktop): enforce selected view policies across capture and export

* feat(runtime): make Frida and LLDB retention budgets selectable

* feat(native): expose diagnostic budgets and preserve exhaustion causes

* feat(managed): expose recoverable snapshot and representation budgets

* feat(metadata): make Go and Rust inspection budgets recoverable

* feat(wasm): expose representation and producer admissions

* feat(evm): expose per-call worker resource budgets

* feat(android): make resource and string-pool omissions recoverable

* feat(producers): expose command and recorded-capture budgets

* docs(analysis): record recovery contracts and integrated validation

* fix(docs): link calibration oracle from published verification pages

* fix(docs): restore desktop task anchors and receipt links

* test(analysis): align fixtures with selectable budget contracts

* fix(analysis): remove source-location projector dependency cycle

* test(analysis): refresh budget recovery and verifier regressions

* test(analysis): preserve format and publication recovery expectations

* test(windows): align conformance with owned runtime admission

* fix(desktop): preserve selected alias kinds in exported state

* test(analysis): align provider fixtures with recoverable budgets

* test(desktop): validate emitted alias metadata structurally

* fix(ghidra): classify bounded Windows endpoint refusals

* test(cli): assert selectable artifact admission recovery

* fix(cli): preserve capture provenance in environment builds
2026-11-10 05:11:20 -05:00

200 lines
6.7 KiB
TypeScript

import { desktopLibraryPolicy } from "../domain/desktop/libraryPolicy.js";
import { existsSync } from "node:fs";
import { mkdir, realpath, symlink, writeFile } from "node:fs/promises";
import { join } from "node:path";
import { describe, expect, it } from "vitest";
import { runHostQuery } from "./HostQuery.js";
import { inspectLibraryPackages } from "./LibraryPackageInventory.js";
import { elfImage } from "../domain/desktop/elfImage.fixture.js";
import { createTestTempDirectory } from "../../tests/fixtures/temporaryDirectory.js";
describe.skipIf(
process.platform !== "linux" || !existsSync("/var/lib/dpkg/status"),
)("inspectLibraryPackages on a Debian host", () => {
it("maps the running node binary's libraries to their packages", async () => {
const executable = await realpath(process.execPath);
const libraries = await inspectLibraryPackages(
executable,
"nodejs",
runHostQuery,
undefined,
);
expect(libraries).not.toHaveProperty("library_packages_reason");
expect(libraries.library_packages).toContain("libc6");
expect(libraries.missing_libraries).toEqual([]);
});
it("explains a launcher script instead of reading it as ELF", async () => {
const libraries = await inspectLibraryPackages(
"/usr/bin/ldd",
"libc-bin",
runHostQuery,
undefined,
);
expect(libraries).toEqual({
library_packages: [],
missing_libraries: [],
unpackaged_libraries: [],
library_packages_reason: expect.stringMatching(
/\/usr\/bin\/ldd.*not read.*not an ELF image/iu,
),
});
});
});
it.skipIf(process.platform === "win32")(
"preserves completed ownership batches when a later query fails",
async () => {
const root = await createTestTempDirectory("rea-library-owners-");
const bin = join(root, "bin");
const lib = join(root, "lib");
await Promise.all([mkdir(bin), mkdir(lib)]);
const paths = Array.from({ length: 102 }, (_, index) =>
join(lib, `lib${index}.so`),
);
const executable = join(bin, "app");
await Promise.all([
writeFile(executable, elfImage({ needed: paths })),
...paths.map((path) => writeFile(path, elfImage({}))),
]);
let batches = 0;
const result = await inspectLibraryPackages(
executable,
"app",
async (command) => {
if (command === "ldconfig") return { stdout: "", exitCode: 0 };
batches++;
if (batches === 1) return { stdout: `owner: ${paths[0]}`, exitCode: 1 };
return { stdout: "", exitCode: 2 };
},
undefined,
);
expect(batches).toBe(2);
expect(result.library_packages).toEqual(["owner"]);
expect(result.unpackaged_libraries).toContain(paths[1]);
expect(result.unpackaged_libraries).not.toContain(paths[101]);
expect(result.library_packages_reason).toContain("dpkg-query");
},
);
it.skipIf(process.platform === "win32")(
"keeps ownership unknown for paths dpkg would interpret as patterns",
async () => {
const root = await createTestTempDirectory("rea-library-pattern-");
const bin = join(root, "bin");
const lib = join(root, "lib[1]");
await Promise.all([mkdir(bin), mkdir(lib)]);
const library = join(lib, "libpattern.so");
const executable = join(bin, "app");
await Promise.all([
writeFile(executable, elfImage({ needed: [library] })),
writeFile(library, elfImage({})),
]);
const result = await inspectLibraryPackages(
executable,
"app",
async (command) => {
if (command === "ldconfig") return { stdout: "", exitCode: 0 };
throw new Error("pattern path must not be passed to dpkg-query");
},
undefined,
);
expect(result.unpackaged_libraries).toEqual([]);
expect(result.library_packages_reason).toContain("pattern characters");
},
);
it.skipIf(process.platform === "win32")(
"does not report a skipped pattern alias when its real path has a known owner",
async () => {
const root = await createTestTempDirectory("rea-library-alias-");
const bin = join(root, "bin");
const lib = join(root, "lib");
await Promise.all([mkdir(bin), mkdir(lib)]);
const physical = join(lib, "physical.so");
const alias = join(lib, "lib[1].so");
const executable = join(bin, "app");
await Promise.all([
writeFile(physical, elfImage({})),
writeFile(executable, elfImage({ needed: [alias] })),
]);
await symlink(physical, alias);
const resolved = await realpath(physical);
const result = await inspectLibraryPackages(
executable,
"app",
async (command, args) => {
if (command === "ldconfig") return { stdout: "", exitCode: 0 };
expect(args).not.toContain(alias);
return { stdout: `lib-owner: ${resolved}`, exitCode: 1 };
},
undefined,
);
expect(result.library_packages).toEqual(["lib-owner"]);
expect(result.unpackaged_libraries).toEqual([]);
expect(result).not.toHaveProperty("library_packages_reason");
},
);
it.skipIf(process.platform === "win32")(
"recovers a 513-library closure with the caller-selected capture policy",
async () => {
const root = await createTestTempDirectory("rea-library-policy-");
const bin = join(root, "bin");
const lib = join(root, "lib");
await Promise.all([mkdir(bin), mkdir(lib)]);
const paths = Array.from({ length: 513 }, (_, index) =>
join(lib, `lib${index}.so`),
);
const executable = join(bin, "app");
await Promise.all([
writeFile(executable, elfImage({ needed: [paths[0] ?? ""] })),
...paths.map((path, index) =>
writeFile(
path,
elfImage({
needed:
paths[index + 1] === undefined ? [] : [paths[index + 1] ?? ""],
}),
),
),
]);
const query = async (command: string, args: readonly string[]) => ({
stdout:
command === "ldconfig"
? ""
: args
.slice(1)
.map((path) => `owner-${paths.indexOf(path)}: ${path}`)
.join("\n"),
exitCode: 0,
});
const limited = await inspectLibraryPackages(
executable,
"app",
query,
undefined,
);
expect(limited.library_packages).toHaveLength(512);
expect(limited.library_packages_reason).toContain(
"library-policy.libraries=512",
);
expect(limited.library_packages_reason).toContain("--library-policy");
const recovered = await inspectLibraryPackages(
executable,
"app",
query,
undefined,
desktopLibraryPolicy({ libraries: 513 }),
);
expect(recovered.library_packages).toHaveLength(513);
expect(recovered.library_packages).toContain("owner-512");
expect(recovered.library_packages_reason).toBeUndefined();
},
);