Files
rea/tests/boundary/cli/procedureAliasSearchCli.test.ts
Kaoru0822andClaude Opus 5.5 44b6384009 fix(native): find procedures by the secondary names exact lookup accepts (#8520)
* fix(native): find procedures by the secondary names exact lookup accepts

search_procedures matched only each procedure's primary name, while exact
lookup also accepts Kuna inventory aliases (versioned-symbol and generated
sub_ names) and Ghidra symbols at an exact function entry. A search for a
name procedure_address resolves returned nothing, and trace_feature
silently missed the procedure.

Both providers now match the same names their exact lookup accepts. A
procedure still appears once under its primary name; the optional
matched_aliases field lists the secondary names that matched, so aliases
never become procedures of their own and list_procedures is unchanged.
The shared domain helper owns that row rule for Kuna and for the Ghidra
host-side Unicode folding pass. The Ghidra analysis profile records the
new search semantics so older snapshots cannot replay alias-blind results.

Fixes #8330

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(ghidra): match leaf spellings of procedure names in search

procedure_address accepts each entry symbol's leaf or namespace-qualified
spelling, but procedure search tested only qualified names, so a regex
such as ^audit_alias$ missed a secondary symbol ns::audit_alias (and ^same$
missed a primary alpha::same) that exact lookup selects.

Lookup and search now share one bridge definition of the names that select
a procedure, so they cannot drift. Matching secondary symbols are still
reported by their qualified names; because a leaf ends its qualified
spelling, the host's Unicode literal pass stays exact over those names.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 08:53:29 -08:00

88 lines
2.6 KiB
TypeScript

import { writeFile } from "node:fs/promises";
import { join } from "node:path";
import { describe, expect } from "vitest";
import { elf } from "../../../src/domain/binaryTarget.fixture.js";
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
import { cliTest } from "../../support/cli/cliFixture.js";
import { writeFakeKuna } from "../providers/kuna/fakeKuna.js";
describe("procedure alias search CLI", () => {
cliTest(
"finds and traces a procedure by an alias exact lookup accepts",
async ({ cli }) => {
const root = await createTestTempDirectory("rea-alias-search-cli-");
const kuna = await writeFakeKuna(root, {
functions: [
{ name: "main", addr: "0x1000" },
{
name: "audit_v1",
addr: "0x1334",
aliases: ["audit_transform", "sub_1334"],
},
{
name: "audit_v2",
addr: "0x133a",
aliases: ["audit_transform", "sub_133a"],
},
],
});
const target = join(root, "target.elf");
await writeFile(target, elf(2, 1, 62));
const run = async (...arguments_: string[]) => {
const result = await cli.run({
arguments: [...arguments_, "--provider", "kuna", "--format", "json"],
cwd: root,
environment: {
REA_LOG_LEVEL: "silent",
REA_KUNA_COMMAND: kuna,
REA_KUNA_CACHE_DIR: join(root, "cache"),
},
});
expect(result.exitCode, JSON.stringify(result.json)).toBe(0);
return result.json;
};
expect(
await run(
"search",
target,
"audit_transform",
"--kind",
"procedures",
"--mode",
"regex",
),
).toMatchObject({
operation: "search_procedures",
normalized_result: [
{
address: "0x1334",
value: "audit_v1",
matched_aliases: ["audit_transform"],
},
{
address: "0x133a",
value: "audit_v2",
matched_aliases: ["audit_transform"],
},
],
});
expect(await run("trace", target, "sub_1334")).toMatchObject({
operation: "trace_feature",
normalized_result: {
matches: [
{
type: "procedure",
address: "0x1334",
value: "audit_v1",
matched_aliases: ["sub_1334"],
},
],
references: [{ target_address: "0x1334", source_address: "0x1004" }],
},
});
},
);
});