diff --git a/src/dotnet/ManagedMemberRows.ts b/src/dotnet/ManagedMemberRows.ts index 6d8cb2f42c..6003efbf77 100644 --- a/src/dotnet/ManagedMemberRows.ts +++ b/src/dotnet/ManagedMemberRows.ts @@ -182,6 +182,7 @@ export const edges = ( const fieldAccesses: ManagedFieldAccess[] = []; for (const method of methods) { for (const anchor of method.body.anchors) { + if (anchor.opcode === "ldtoken") continue; if (anchor.operand_kind === "method" && anchor.operand !== null) { const named = methodCore.get(anchor.operand)?.name ?? diff --git a/src/dotnet/ManagedMetadataHandles.test.ts b/src/dotnet/ManagedMetadataHandles.test.ts new file mode 100644 index 0000000000..e5fc60fa5d --- /dev/null +++ b/src/dotnet/ManagedMetadataHandles.test.ts @@ -0,0 +1,27 @@ +import { expect, it } from "vitest"; +import { inspectManagedMembersBytes } from "./ManagedMemberInspector.js"; +import { + buildManagedPeFixture, + managedPeFixtureTarget, +} from "./ManagedPe.fixture.js"; + +it("retains metadata handles without reporting calls or field accesses", () => { + const il = Buffer.from([ + 0xd0, 0x01, 0, 0, 0x06, 0x26, 0xd0, 0x01, 0, 0, 0x04, 0x26, 0x28, 0x01, 0, + 0, 0x0a, 0x7b, 0x01, 0, 0, 0x04, 0x26, 0x2a, + ]); + const bytes = buildManagedPeFixture({ + ilBody: Buffer.concat([Buffer.from([(il.length << 2) | 2]), il]), + }); + const result = inspectManagedMembersBytes( + bytes, + managedPeFixtureTarget(bytes), + ); + expect( + result.methods[0]?.body.anchors.map((anchor) => anchor.opcode), + ).toEqual(["ldtoken", "ldtoken", "call", "ldfld"]); + expect(result.call_edges.map((edge) => edge.opcode)).toEqual(["call"]); + expect(result.field_accesses.map((access) => access.opcode)).toEqual([ + "ldfld", + ]); +});