[GH-ISSUE #6720] [Bug] Optional VARARG parameters make managed member and function-pointer signatures unsupported #4089

Closed
opened 2026-10-31 00:46:44 +00:00 by bsakaguchi · 0 comments
Owner

Originally created by @coygeek on GitHub (Oct 23, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/6720

Before submitting

  • I searched the open and closed issues for a related report.
  • I removed credentials, tokens, private paths, and sensitive target data.

Area

Native analysis or decompilation

Observed behavior

A valid VARARG MemberRef signature with one fixed int32 parameter and one optional int32 parameter returns kind: "unknown", parse_status: "unsupported", and issue: "unsupported element type 0x41". Its calling convention, return type, parameter count and parameter types become empty or null. A function-pointer field containing the same MethodRefSig fails in the same way. Corresponding signatures with no optional arguments decode completely. The MemberRef failure was also observed through inspect-managed-members; the function-pointer case was checked through the production byte inspector.

Reproduction

Run from the source checkout with its locked dependencies and built CLI runtime. Save and run this production-inspector probe using the pinned Node version. Only output paths below are genericized; the probe uses the repository's synthetic PE fixture builder and never loads or executes managed code.

cat > /tmp/rea-probe.mjs <<'JS'
import { resolve } from 'node:path';
import { pathToFileURL } from 'node:url';
import { mkdir, writeFile } from 'node:fs/promises';
const out = process.env.REA_PROBE_ROOT ?? '/tmp/rea-vararg';
await mkdir(out, {recursive:true});
const load = name => import(pathToFileURL(resolve(name)));
const { buildManagedPeFixture, managedPeFixtureTarget } = await load('src/dotnet/ManagedPe.fixture.ts');
const { inspectManagedMembersBytes } = await load('src/dotnet/ManagedMemberInspector.ts');
for (const [label, options] of [
 ['vararg-fixed-control', { memberRefName: 'Write', memberRefSignature: Buffer.from([0x05, 0x01, 0x01, 0x08]) }],
 ['vararg-optional', { memberRefName: 'Write', memberRefSignature: Buffer.from([0x05, 0x02, 0x01, 0x08, 0x41, 0x08]) }],
 ['fnptr-fixed-control', { fieldSignature: Buffer.from([0x06, 0x1b, 0x05, 0x01, 0x01, 0x08]) }],
 ['fnptr-optional', { fieldSignature: Buffer.from([0x06, 0x1b, 0x05, 0x02, 0x01, 0x08, 0x41, 0x08]) }],
]) {
 const bytes = buildManagedPeFixture({targetFramework:null, ilBody:Buffer.from([0x06,0x2a]), typeReferences:[{namespace:'Fixture',name:'External'}], memberRefParentRaw:17, ...options});
 await writeFile(resolve(out, label + '.dll'), bytes);
 const report=inspectManagedMembersBytes(bytes,managedPeFixtureTarget(bytes,'/tmp/rea-repro/'+label+'.dll'));
 console.log(JSON.stringify({label, signature:label.startsWith('fnptr')?report.fields[0].signature:report.member_refs[0].signature, coverage:report.coverage}));
}
console.log(JSON.stringify({node:process.version,platform:process.platform,architecture:process.arch}));
JS
node --import tsx /tmp/rea-probe.mjs
node scripts/rea.mjs inspect-managed-members /tmp/rea-vararg/vararg-optional.dll --json

The source probe checks four cases. The final probe reproduced both failures and both successful controls; the public CLI reproduced the optional-MemberRef failure once. No assertion about real-world frequency is made.

Expected behavior

Decode the fixed and optional parameter types in the accepted VARARG signatures. ECMA-335, sixth edition, II.23.2.2 defines 0x41 as SENTINEL separating the fixed and optional parameters of a MethodRefSig; ParamCount includes parameters on both sides. II.23.2.12 permits FNPTR MethodRefSig as a Type. The tested blobs follow those productions. REA's method-header grammar explicitly accepts VARARG for member and function-pointer signatures.

Impact and scope

Static member inspection loses decoded signature facts for these ordinary optional-argument call-site signatures and reports partial coverage. This is a bounded metadata-decoding failure; the original input and raw signature digest remain intact. Runtime observations cover synthetic PE artifacts, the production inspector, and the MemberRef CLI projection on Linux. A compiler-produced assembly, MCP transport, managed execution and downstream member comparison were not tested. No tested workaround recovers the decoded facts through the public inspection interface.

REA version

Source package rea-agents 6.7.0, revision 5d6b8a0ab693c03ab85cf0807d40bedf021e76d8; source inspector and supplied built CLI runtime. Published npm-package execution was not tested.

Runtime and platform

Node v24.22.1; Linux x86_64; repository locked dependencies. No external managed compiler, runtime or analysis engine was used.

Target and artifact context

Benign synthetic PE/CLI metadata built with buildManagedPeFixture. MemberRef signature bytes: control 05 01 01 08; failing 05 02 01 08 41 08. Field signature bytes: control 06 1b 05 01 01 08; failing 06 1b 05 02 01 08 41 08. Each fixture has an inert void-returning method body and no custom attributes. MemberRefs name Fixture.External.Write. No target code executes.

Interface

CLI

Earliest failure stage

Native analysis or reconstruction

Relevant output or evidence

Observed source-inspector results, projected to the relevant fields:

vararg-fixed-control: kind=method parse_status=decoded calling_convention=vararg parameter_count=1 parameter_types=["i4"] return_type=void coverage=complete
vararg-optional: kind=unknown parse_status=unsupported calling_convention=null parameter_count=null parameter_types=[] return_type=null issue="unsupported element type 0x41" coverage=partial
fnptr-fixed-control: kind=field parse_status=decoded field_type="fnptr[vararg](i4)->void" coverage=complete
fnptr-optional: kind=unknown parse_status=unsupported field_type=null issue="unsupported element type 0x41" coverage=partial

The CLI exited 0 and returned operation: "inspect_managed_members", member_refs[0].parent_name: "Fixture.External", the same unsupported MemberRef signature, and coverage: {"state":"partial","issues":[]}. Evidence provenance is observed, local verification is reproduced, and reproduction completeness is complete for these synthetic static artifacts. The format contract is established separately by the specification cited above.

Typed outcome or recovery expected

The optional MemberRef signature should retain method kind, VARARG calling convention, void return type and both i4 parameter types. The function-pointer field should retain field kind and its decoded type. Restoration should preserve the two no-optional-argument controls. This is a proposed restoration check; no fix was made or tested.

Analysis or suspected cause

Source-derived: the member parameter loop passes every next byte directly to readTypeSignature. The function-pointer continuation likewise counts return/parameter types without consuming a sentinel. SENTINEL is a method-signature delimiter rather than a standalone type, so both paths reach the unsupported-element branch. The failure projection clears the decoded facts.

Additional context

The supplied open-issue snapshot and retained recent snapshots were searched across titles and bodies for VARARG, SENTINEL, optional parameters and function-pointer signatures. No matching managed-signature report was found there; fresh open/closed searches and a read of the latest created open issues found no matching report immediately before submission. This report groups the MemberRef and function-pointer symptoms under the same missing signature-delimiter behavior.

Triage assessment

  • Impact level: P2
  • Assessment status: supported
  • Impact basis: The tested valid optional-argument signatures lose their method or field type facts through static inspection while equivalent controls decode; the failure is bounded, surfaced as partial coverage, and does not mutate input artifacts.
  • Workaround status: unverified
  • Workaround basis: No alternate public inspection path was observed recovering these decoded facts. Original bytes and raw hashes remain available, but an independent decoding workflow was not tested.
Originally created by @coygeek on GitHub (Oct 23, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/6720 ## Before submitting - [x] I searched the open and closed issues for a related report. - [x] I removed credentials, tokens, private paths, and sensitive target data. ## Area Native analysis or decompilation ## Observed behavior A valid VARARG MemberRef signature with one fixed `int32` parameter and one optional `int32` parameter returns `kind: "unknown"`, `parse_status: "unsupported"`, and `issue: "unsupported element type 0x41"`. Its calling convention, return type, parameter count and parameter types become empty or null. A function-pointer field containing the same MethodRefSig fails in the same way. Corresponding signatures with no optional arguments decode completely. The MemberRef failure was also observed through `inspect-managed-members`; the function-pointer case was checked through the production byte inspector. ## Reproduction Run from the source checkout with its locked dependencies and built CLI runtime. Save and run this production-inspector probe using the pinned Node version. Only output paths below are genericized; the probe uses the repository's synthetic PE fixture builder and never loads or executes managed code. ```sh cat > /tmp/rea-probe.mjs <<'JS' import { resolve } from 'node:path'; import { pathToFileURL } from 'node:url'; import { mkdir, writeFile } from 'node:fs/promises'; const out = process.env.REA_PROBE_ROOT ?? '/tmp/rea-vararg'; await mkdir(out, {recursive:true}); const load = name => import(pathToFileURL(resolve(name))); const { buildManagedPeFixture, managedPeFixtureTarget } = await load('src/dotnet/ManagedPe.fixture.ts'); const { inspectManagedMembersBytes } = await load('src/dotnet/ManagedMemberInspector.ts'); for (const [label, options] of [ ['vararg-fixed-control', { memberRefName: 'Write', memberRefSignature: Buffer.from([0x05, 0x01, 0x01, 0x08]) }], ['vararg-optional', { memberRefName: 'Write', memberRefSignature: Buffer.from([0x05, 0x02, 0x01, 0x08, 0x41, 0x08]) }], ['fnptr-fixed-control', { fieldSignature: Buffer.from([0x06, 0x1b, 0x05, 0x01, 0x01, 0x08]) }], ['fnptr-optional', { fieldSignature: Buffer.from([0x06, 0x1b, 0x05, 0x02, 0x01, 0x08, 0x41, 0x08]) }], ]) { const bytes = buildManagedPeFixture({targetFramework:null, ilBody:Buffer.from([0x06,0x2a]), typeReferences:[{namespace:'Fixture',name:'External'}], memberRefParentRaw:17, ...options}); await writeFile(resolve(out, label + '.dll'), bytes); const report=inspectManagedMembersBytes(bytes,managedPeFixtureTarget(bytes,'/tmp/rea-repro/'+label+'.dll')); console.log(JSON.stringify({label, signature:label.startsWith('fnptr')?report.fields[0].signature:report.member_refs[0].signature, coverage:report.coverage})); } console.log(JSON.stringify({node:process.version,platform:process.platform,architecture:process.arch})); JS node --import tsx /tmp/rea-probe.mjs node scripts/rea.mjs inspect-managed-members /tmp/rea-vararg/vararg-optional.dll --json ``` The source probe checks four cases. The final probe reproduced both failures and both successful controls; the public CLI reproduced the optional-MemberRef failure once. No assertion about real-world frequency is made. ## Expected behavior Decode the fixed and optional parameter types in the accepted VARARG signatures. ECMA-335, sixth edition, [II.23.2.2](https://www.ecma-international.org/wp-content/uploads/ECMA-335_6th_edition_june_2012.pdf) defines `0x41` as SENTINEL separating the fixed and optional parameters of a MethodRefSig; ParamCount includes parameters on both sides. II.23.2.12 permits `FNPTR MethodRefSig` as a Type. The tested blobs follow those productions. REA's [method-header grammar explicitly accepts VARARG for member and function-pointer signatures](https://github.com/morluto/rea/blob/5d6b8a0ab693c03ab85cf0807d40bedf021e76d8/src/dotnet/ManagedMemberInspectorCore.ts#L358-L364). ## Impact and scope Static member inspection loses decoded signature facts for these ordinary optional-argument call-site signatures and reports partial coverage. This is a bounded metadata-decoding failure; the original input and raw signature digest remain intact. Runtime observations cover synthetic PE artifacts, the production inspector, and the MemberRef CLI projection on Linux. A compiler-produced assembly, MCP transport, managed execution and downstream member comparison were not tested. No tested workaround recovers the decoded facts through the public inspection interface. ## REA version Source package `rea-agents` 6.7.0, revision `5d6b8a0ab693c03ab85cf0807d40bedf021e76d8`; source inspector and supplied built CLI runtime. Published npm-package execution was not tested. ## Runtime and platform Node v24.22.1; Linux x86_64; repository locked dependencies. No external managed compiler, runtime or analysis engine was used. ## Target and artifact context Benign synthetic PE/CLI metadata built with `buildManagedPeFixture`. MemberRef signature bytes: control `05 01 01 08`; failing `05 02 01 08 41 08`. Field signature bytes: control `06 1b 05 01 01 08`; failing `06 1b 05 02 01 08 41 08`. Each fixture has an inert void-returning method body and no custom attributes. MemberRefs name `Fixture.External.Write`. No target code executes. ## Interface CLI ## Earliest failure stage Native analysis or reconstruction ## Relevant output or evidence Observed source-inspector results, projected to the relevant fields: ```text vararg-fixed-control: kind=method parse_status=decoded calling_convention=vararg parameter_count=1 parameter_types=["i4"] return_type=void coverage=complete vararg-optional: kind=unknown parse_status=unsupported calling_convention=null parameter_count=null parameter_types=[] return_type=null issue="unsupported element type 0x41" coverage=partial fnptr-fixed-control: kind=field parse_status=decoded field_type="fnptr[vararg](i4)->void" coverage=complete fnptr-optional: kind=unknown parse_status=unsupported field_type=null issue="unsupported element type 0x41" coverage=partial ``` The CLI exited 0 and returned `operation: "inspect_managed_members"`, `member_refs[0].parent_name: "Fixture.External"`, the same unsupported MemberRef signature, and `coverage: {"state":"partial","issues":[]}`. Evidence provenance is observed, local verification is reproduced, and reproduction completeness is complete for these synthetic static artifacts. The format contract is established separately by the specification cited above. ## Typed outcome or recovery expected The optional MemberRef signature should retain method kind, VARARG calling convention, void return type and both `i4` parameter types. The function-pointer field should retain field kind and its decoded type. Restoration should preserve the two no-optional-argument controls. This is a proposed restoration check; no fix was made or tested. ## Analysis or suspected cause Source-derived: [the member parameter loop passes every next byte directly to `readTypeSignature`](https://github.com/morluto/rea/blob/5d6b8a0ab693c03ab85cf0807d40bedf021e76d8/src/dotnet/ManagedMemberInspectorCore.ts#L872-L880). The [function-pointer continuation likewise counts return/parameter types without consuming a sentinel](https://github.com/morluto/rea/blob/5d6b8a0ab693c03ab85cf0807d40bedf021e76d8/src/dotnet/ManagedMemberInspectorCore.ts#L645-L670). SENTINEL is a method-signature delimiter rather than a standalone type, so both paths reach the unsupported-element branch. The [failure projection clears the decoded facts](https://github.com/morluto/rea/blob/5d6b8a0ab693c03ab85cf0807d40bedf021e76d8/src/dotnet/ManagedMemberInspectorCore.ts#L893-L915). ## Additional context The supplied open-issue snapshot and retained recent snapshots were searched across titles and bodies for VARARG, SENTINEL, optional parameters and function-pointer signatures. No matching managed-signature report was found there; fresh open/closed searches and a read of the latest created open issues found no matching report immediately before submission. This report groups the MemberRef and function-pointer symptoms under the same missing signature-delimiter behavior. ## Triage assessment - Impact level: P2 - Assessment status: supported - Impact basis: The tested valid optional-argument signatures lose their method or field type facts through static inspection while equivalent controls decode; the failure is bounded, surfaced as partial coverage, and does not mutate input artifacts. - Workaround status: unverified - Workaround basis: No alternate public inspection path was observed recovering these decoded facts. Original bytes and raw hashes remain available, but an independent decoding workflow was not tested.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#4089
No description provided.