[GH-ISSUE #6801] [Bug] Objective-C++ property type encodings are split at template argument commas #4150

Closed
opened 2026-10-31 00:47:12 +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/6801

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

The prepared production property parser turns T{vector<float, float, float>=},N,V_position into type_encoding: "{vector<float" and invents two attributes named " " from the remaining type fragments. The same result appears through decodeAppleDispatchMetadata on a generated Mach-O metadata fixture; the class remains decoded and objc_properties_categories coverage remains complete.

These are executed production-boundary observations on generated metadata, not CLI/MCP or Apple compiler executions. The valid Objective-C++ input basis is source-derived from LLVM below.

Reproduction

From the prepared checkout root, this is the minimal parser reproduction actually executed:

node --input-type=module <<'JS'
import { parsePropertyAttributes } from './dist/native/AppleObjcProperties.js';
for (const attributes of [
  'T{vector<float, float, float>=},N,V_position',
  'T{vector<float>=},N,V_position',
  'T{Point=dd},N,V_position'
]) {
  console.log(JSON.stringify({attributes, result:parsePropertyAttributes('position', attributes)}));
}
JS

The comma-bearing type is truncated; the two controls retain their full types. Separately, six generated 4096-byte thin arm64 Mach-O metadata fixtures containing this property and an independent scalar sibling were passed to the prepared decodeAppleDispatchMetadata export. Both comma-bearing variants failed identically; scalar/custom-accessor, quoted-comma object, ordinary-struct, and single-template-argument controls preserved their types. Both six-case executions and the minimal reproduction completed before this draft. Sibling properties survived in every case.

Expected behavior

Preserve {vector<float, float, float>=} as the complete T attribute and type_encoding, with N and V remaining separate attributes. Commas inside a C++ aggregate type name must not become property attribute separators.

REA documents preservation of each encoded property attribute. LLVM's released Objective-C++ encoding test contains this comma-bearing aggregate encoding and corresponding property declarations. Its property encoder appends the encoded property type after T; the aggregate encoder prints template arguments into that type. Applicability to compiler-generated binaries is source-derived; no compiler was executed here.

Impact and scope

Bounded incorrect native metadata: consumers receive a truncated structured property type and false attribute identities without an incompleteness signal. Observed for both comma-bearing variants in both generated-fixture runs. Real-application frequency, other aggregate forms, macOS, and public transports were not tested.

A verified manual-inspection workaround recovers the original attribute string exactly with property.attributes.map(a => a.name+a.value).join(','); the complete type can then be read from that string. This leaves the structured fields incorrect and does not modify the artifact.

REA version

rea-agents 6.7.0; fixed source revision bd4f5e9c197ba942ed026c9fed6ff3fae663901d; prepared production dist.

Runtime and platform

Linux x64. Initial generated-fixture run: Node.js v24.22.1. Repeated generated-fixture run and minimal reproduction: Node.js v26.12.1. No Hopper, Ghidra, Apple SDK, or target execution.

Target and artifact context

Self-authored little-endian 64-bit arm64 Mach-O metadata fixtures with a root class, two property records, and in-bounds NUL-terminated attribute strings; no compiler-generated executable was tested. The minimal reproduction invokes the same production attribute parser directly without a target artifact.

Interface

Other

Earliest failure stage

Native analysis or reconstruction

Relevant output or evidence

Executed minimal reproduction's first result, abbreviated:

{
  "name": "position",
  "type_encoding": "{vector<float",
  "attributes": [
    {"name":"T","value":"{vector<float"},
    {"name":" ","value":"float"},
    {"name":" ","value":"float>=}"},
    {"name":"N","value":""},
    {"name":"V","value":"_position"}
  ]
}

The generated-fixture decoder also returns class decode: {"status":"decoded","reason":null} and objc_properties_categories: {"status":"complete","reason":null}. The sibling retains type q and read-only state. Evidence provenance: executed production parser/decoder boundaries; compiler applicability: source-derived. CLI/MCP, native-provider, and real-compiler verification were not run.

Typed outcome or recovery expected

Return the complete encoded type and correct attribute identities while retaining the sibling property. If the encoding cannot be interpreted, retain the source metadata with explicit partial/unsupported coverage rather than silently splitting its type.

Analysis or suspected cause

Source-derived explanation of the observed result: splitAttributes tracks quotes but splits every unquoted comma, including aggregate type-name commas. Type/attribute projection treats the resulting fragments as independent attributes. The class consumer returns them unchanged.

Additional context

Searched the supplied 1,057 open issues and title inventory, plus six targeted closed-issue searches. No matching report found. Related closed #3336 concerns malformed property pointer/name records; closed #3345 concerns unfinished quoted types. #5707 concerns protocol-property omission. This report concerns valid class-property type metadata. No last known good version established. Prepared with AI assistance.

Triage assessment

  • Impact level: P2
  • Assessment status: supported
  • Impact basis: Executed production-boundary probes return incorrect structured type and attribute identities for comma-bearing C++ aggregate encodings while reporting complete coverage; sibling data survives. Real-application prevalence remains unmeasured.
  • Workaround status: available
  • Workaround basis: Every executed generated-fixture case reconstructed its original attribute string exactly from the returned ordered name/value tokens, allowing manual inspection of the full type without changing the artifact; structured projection remains incorrect.
Originally created by @coygeek on GitHub (Oct 23, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/6801 ## 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 The prepared production property parser turns `T{vector<float, float, float>=},N,V_position` into `type_encoding: "{vector<float"` and invents two attributes named `" "` from the remaining type fragments. The same result appears through `decodeAppleDispatchMetadata` on a generated Mach-O metadata fixture; the class remains decoded and `objc_properties_categories` coverage remains complete. These are executed production-boundary observations on generated metadata, not CLI/MCP or Apple compiler executions. The valid Objective-C++ input basis is source-derived from LLVM below. ## Reproduction From the prepared checkout root, this is the minimal parser reproduction actually executed: ```sh node --input-type=module <<'JS' import { parsePropertyAttributes } from './dist/native/AppleObjcProperties.js'; for (const attributes of [ 'T{vector<float, float, float>=},N,V_position', 'T{vector<float>=},N,V_position', 'T{Point=dd},N,V_position' ]) { console.log(JSON.stringify({attributes, result:parsePropertyAttributes('position', attributes)})); } JS ``` The comma-bearing type is truncated; the two controls retain their full types. Separately, six generated 4096-byte thin arm64 Mach-O metadata fixtures containing this property and an independent scalar sibling were passed to the prepared `decodeAppleDispatchMetadata` export. Both comma-bearing variants failed identically; scalar/custom-accessor, quoted-comma object, ordinary-struct, and single-template-argument controls preserved their types. Both six-case executions and the minimal reproduction completed before this draft. Sibling properties survived in every case. ## Expected behavior Preserve `{vector<float, float, float>=}` as the complete `T` attribute and `type_encoding`, with `N` and `V` remaining separate attributes. Commas inside a C++ aggregate type name must not become property attribute separators. REA [documents preservation of each encoded property attribute](https://github.com/morluto/rea/blob/bd4f5e9c197ba942ed026c9fed6ff3fae663901d/docs/native-investigation.md#L555-L563). LLVM's released [Objective-C++ encoding test](https://github.com/llvm/llvm-project/blob/llvmorg-20.1.8/clang/test/CodeGenObjCXX/encode.mm#L5-L35) contains this comma-bearing aggregate encoding and corresponding property declarations. Its [property encoder](https://github.com/llvm/llvm-project/blob/llvmorg-20.1.8/clang/lib/AST/ASTContext.cpp#L8633-L8698) appends the encoded property type after `T`; the [aggregate encoder](https://github.com/llvm/llvm-project/blob/llvmorg-20.1.8/clang/lib/AST/ASTContext.cpp#L9102-L9122) prints template arguments into that type. Applicability to compiler-generated binaries is source-derived; no compiler was executed here. ## Impact and scope Bounded incorrect native metadata: consumers receive a truncated structured property type and false attribute identities without an incompleteness signal. Observed for both comma-bearing variants in both generated-fixture runs. Real-application frequency, other aggregate forms, macOS, and public transports were not tested. A verified manual-inspection workaround recovers the original attribute string exactly with `property.attributes.map(a => a.name+a.value).join(',')`; the complete type can then be read from that string. This leaves the structured fields incorrect and does not modify the artifact. ## REA version `rea-agents` 6.7.0; fixed source revision `bd4f5e9c197ba942ed026c9fed6ff3fae663901d`; prepared production `dist`. ## Runtime and platform Linux x64. Initial generated-fixture run: Node.js v24.22.1. Repeated generated-fixture run and minimal reproduction: Node.js v26.12.1. No Hopper, Ghidra, Apple SDK, or target execution. ## Target and artifact context Self-authored little-endian 64-bit arm64 Mach-O metadata fixtures with a root class, two property records, and in-bounds NUL-terminated attribute strings; no compiler-generated executable was tested. The minimal reproduction invokes the same production attribute parser directly without a target artifact. ## Interface Other ## Earliest failure stage Native analysis or reconstruction ## Relevant output or evidence Executed minimal reproduction's first result, abbreviated: ```json { "name": "position", "type_encoding": "{vector<float", "attributes": [ {"name":"T","value":"{vector<float"}, {"name":" ","value":"float"}, {"name":" ","value":"float>=}"}, {"name":"N","value":""}, {"name":"V","value":"_position"} ] } ``` The generated-fixture decoder also returns class `decode: {"status":"decoded","reason":null}` and `objc_properties_categories: {"status":"complete","reason":null}`. The sibling retains type `q` and read-only state. Evidence provenance: executed production parser/decoder boundaries; compiler applicability: source-derived. CLI/MCP, native-provider, and real-compiler verification were not run. ## Typed outcome or recovery expected Return the complete encoded type and correct attribute identities while retaining the sibling property. If the encoding cannot be interpreted, retain the source metadata with explicit partial/unsupported coverage rather than silently splitting its type. ## Analysis or suspected cause Source-derived explanation of the observed result: [splitAttributes](https://github.com/morluto/rea/blob/bd4f5e9c197ba942ed026c9fed6ff3fae663901d/src/native/AppleObjcProperties.ts#L70-L91) tracks quotes but splits every unquoted comma, including aggregate type-name commas. [Type/attribute projection](https://github.com/morluto/rea/blob/bd4f5e9c197ba942ed026c9fed6ff3fae663901d/src/native/AppleObjcProperties.ts#L33-L53) treats the resulting fragments as independent attributes. The [class consumer](https://github.com/morluto/rea/blob/bd4f5e9c197ba942ed026c9fed6ff3fae663901d/src/native/AppleObjcDispatchFacets.ts#L350-L387) returns them unchanged. ## Additional context Searched the supplied 1,057 open issues and title inventory, plus six targeted closed-issue searches. No matching report found. Related closed [#3336](https://github.com/morluto/rea/issues/3336) concerns malformed property pointer/name records; closed [#3345](https://github.com/morluto/rea/issues/3345) concerns unfinished quoted types. [#5707](https://github.com/morluto/rea/issues/5707) concerns protocol-property omission. This report concerns valid class-property type metadata. No last known good version established. Prepared with AI assistance. ## Triage assessment - Impact level: P2 - Assessment status: supported - Impact basis: Executed production-boundary probes return incorrect structured type and attribute identities for comma-bearing C++ aggregate encodings while reporting complete coverage; sibling data survives. Real-application prevalence remains unmeasured. - Workaround status: available - Workaround basis: Every executed generated-fixture case reconstructed its original attribute string exactly from the returned ordered name/value tokens, allowing manual inspection of the full type without changing the artifact; structured projection remains incorrect.
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#4150
No description provided.