mirror of
https://github.com/morluto/rea
synced 2026-10-25 22:08:11 -04:00
@@ -155,6 +155,8 @@ export interface ArtifactTraversalOmission {
|
||||
export interface ArtifactReaderTraversal {
|
||||
readonly status: ArtifactInventoryCoverage["status"];
|
||||
readonly limitations: readonly string[];
|
||||
/** Number of directory entries examined, including names omitted before decoding. */
|
||||
readonly examinedEntries?: number;
|
||||
}
|
||||
|
||||
/** Per-iterator observation sink; adapters report intentional omissions without shared state. */
|
||||
|
||||
@@ -271,6 +271,12 @@ const scanDirectory = async (
|
||||
kind: omission.kind,
|
||||
});
|
||||
},
|
||||
onCoverage: (coverage) => {
|
||||
if (coverage.examinedEntries !== undefined)
|
||||
entries = coverage.examinedEntries;
|
||||
if (coverage.status !== "complete") partial = true;
|
||||
limitations.push(...coverage.limitations);
|
||||
},
|
||||
})) {
|
||||
entries++;
|
||||
abortIfNeeded(signal);
|
||||
|
||||
@@ -132,6 +132,7 @@ export class DirectoryArtifactReader implements ArtifactReader {
|
||||
if (unrepresentableNameCount > 0)
|
||||
options?.onCoverage?.({
|
||||
status: "unknown",
|
||||
examinedEntries: examined,
|
||||
limitations: [
|
||||
`Directory contains ${String(unrepresentableNameCount)} entry name(s) that are not valid UTF-8; no filesystem operations were performed for them. First raw basename bytes: ${firstUnrepresentableNameHex ?? "unknown"}.`,
|
||||
],
|
||||
|
||||
@@ -53,6 +53,35 @@ const put = async (root: string, path: string, bytes: Buffer | string) => {
|
||||
await writeFile(destination, bytes);
|
||||
};
|
||||
|
||||
it.skipIf(process.platform !== "linux")(
|
||||
"keeps desktop sibling files with partial coverage for invalid UTF-8 names",
|
||||
async () => {
|
||||
const root = await createTestTempDirectory("rea-desktop-filename-bytes-");
|
||||
const rawName = Buffer.from([
|
||||
0x62, 0x61, 0x64, 0xff, 0x2e, 0x74, 0x78, 0x74,
|
||||
]);
|
||||
const rawPath = Buffer.concat([Buffer.from(`${root}/`), rawName]);
|
||||
await Promise.all([
|
||||
writeFile(rawPath, "RAW_FILE"),
|
||||
writeFile(join(root, "bad\ufffd.txt"), "UNICODE_FILE"),
|
||||
writeFile(join(root, "good.txt"), "GOOD_FILE"),
|
||||
]);
|
||||
|
||||
const { report } = await inspect(root);
|
||||
expect(report.coverage).toMatchObject({
|
||||
status: "partial",
|
||||
entries_examined: 3,
|
||||
});
|
||||
expect(
|
||||
report.files.filter(({ path }) => path === "bad\ufffd.txt"),
|
||||
).toHaveLength(1);
|
||||
expect(report.files.map(({ path }) => path)).toContain("good.txt");
|
||||
expect(report.limitations.join(" ")).toContain(
|
||||
`First raw basename bytes: ${rawName.toString("hex")}`,
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
it("joins real PE/CLI reference facts and independent engine markers without picking a winner", async () => {
|
||||
const root = await createTestTempDirectory("rea-desktop-mixed-");
|
||||
await put(
|
||||
|
||||
Reference in New Issue
Block a user