fix(exports): preserve ELF name byte identity

This commit is contained in:
morluto committed 2026-10-27 12:17:29 +08:00
1 parent 1cd82597da
commit 14dd07e740
4 files changed
+199 -24

No files matched your search

+39 -2
View File
@@ -38,7 +38,12 @@ export const nativeExportsViewRequestSchema = z.discriminatedUnion(
z.strictObject({
...page,
collection: z.literal("exports"),
names: z.array(z.string()).optional(),
names: z
.array(z.string())
.optional()
.describe(
"Exact PE names, or UTF-8 ELF source names. ELF display fallbacks and names with unknown encoding are not identities; use indices for those rows. Omitted includes all names; [] matches none.",
),
indices: z.array(z.int().nonnegative()).optional(),
fields: z.array(z.union([peRow.keyof(), elfRow.keyof()])).optional(),
}),
@@ -174,6 +179,32 @@ export const projectNativeExportsView = (
`Selected export fields do not belong to ${report.format}; available fields: ${allowed.join(", ")}.`,
);
const names = view.names === undefined ? undefined : new Set(view.names);
const encodedNames =
names === undefined
? undefined
: new Set(
[...names].flatMap((name) => {
const bytes = Buffer.from(name, "utf8");
return bytes.toString("utf8") === name
? [bytes.toString("base64")]
: [];
}),
);
if (
names !== undefined &&
names.size > 0 &&
report.format === "elf" &&
report.exports.some(
(row) =>
row.name_utf8_decodable === null ||
(row.name_utf8_decodable &&
row.name_bytes_base64 === null &&
!/^[\x00-\x7f]*$/u.test(row.name)),
)
)
shared.unknowns.push(
"Some ELF names lack retained encoding facts and cannot be matched by UTF-8 identity; select their source indices. A no-match page does not establish their absence.",
);
// A projected decoded name still carries its exact bytes and encoding qualification.
const columns = new Set<string>(fields);
if (report.format === "elf" && columns.has("name")) {
@@ -204,7 +235,13 @@ export const projectNativeExportsView = (
view,
(row, index) =>
(indices === undefined || indices.has(index)) &&
(names === undefined || (row.name !== null && names.has(row.name))),
(names === undefined ||
("name_utf8_decodable" in row
? row.name_utf8_decodable === true &&
(row.name_bytes_base64 !== null
? encodedNames!.has(row.name_bytes_base64)
: /^[\x00-\x7f]*$/u.test(row.name) && names.has(row.name))
: row.name !== null && names.has(row.name))),
projectRow,
);
return ok({