[GH-ISSUE #5580] [Bug] get_objc_protocols counts Objective-C method labels containing _TtP as protocols #3390

Closed
opened 2026-10-31 00:39:50 +00:00 by bsakaguchi · 1 comment
Owner

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

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

On an Objective-C executable with no protocol declaration and no Swift source, MCP get_objc_protocols with {} returns count: 2: the method label -[Widget _TtPing] and its message-send shim _objc_msgSend$_TtPing. The independent verifier reproduced this through the production MCP server with provider_id: "hopper"; all open, analysis, and close calls succeeded.

Reproduction

The independent verifier compiled this reduced fixture against the source baseline below:

mkdir -p repro
cat > repro/widget.m <<'OBJC'
#import <Foundation/Foundation.h>
@interface Widget : NSObject
- (void)_TtPing;
@end
@implementation Widget
- (void)_TtPing { }
@end
int main(void) {
    [[[Widget alloc] init] _TtPing];
    return 0;
}
OBJC
clang -fobjc-arc -framework Foundation repro/widget.m -o repro/widget_protocol
  1. Start the built production server with node scripts/rea.mjs mcp using a stdio MCP client and initialize the connection.
  2. Call open_binary with {"path":"<absolute path to repro/widget_protocol>","provider_id":"hopper"}. Resolve the fixture path with python3 -c 'from pathlib import Path; print(Path("repro/widget_protocol").resolve())'.
  3. Call get_objc_protocols with {} and inspect structuredContent.normalized_result.
  4. Call close_binary with {}.

The verifier executed this sequence once for each of three separately compiled fixtures, closing each before opening the next. Renaming the selector to TtPing returned {"count":0,"protocols":[]}. A separate positive control declaring @protocol LocalProtocol and conforming Widget returned one genuine protocol label. The replay used isolated home/configuration directories; the server exited successfully. No new Hopper session was run during submission.

Expected behavior

Return {"count":0,"protocols":[]} for the original fixture, as for the renamed-selector control. A method implementation and a message-send shim are not protocol labels.

src/contracts/enhancedToolContracts.ts:39-41, independently confirmed through production MCP tools/list, promises discovery and deduplication of Objective-C and Swift protocol labels. Genuine protocol labels must remain discoverable.

Impact and scope

The tested valid Objective-C input produces two false protocol inventory entries and an incorrect count. This is a bounded P2 impact assessment. Callers can discard the observed Objective-C method/shim forms and recompute the count; the verifier checked that workaround against all three captured results, retaining the genuine protocol control.

Other providers, prevalence in ordinary binaries, and all Swift mangling forms were not tested. No security-boundary failure was observed.

REA version

6.7.0; source commit 074768901f3cdc8205b61773fb1faf6f6c7b3ca8.

Runtime and platform

macOS arm64; Hopper Disassembler 6.1.0-demo, selected explicitly. NOT_ENOUGH_INFO: the verifier did not record the exact Node.js version or macOS release. A licensed Hopper distribution was not tested.

Target and artifact context

Self-built arm64 Mach-O Objective-C executable linked against Foundation, with no protocol declaration or Swift source; selector-renamed negative control and genuine Objective-C protocol positive control.

Interface

MCP

Earliest failure stage

Native analysis or reconstruction

Relevant output or evidence

The independent verifier observed this structuredContent.normalized_result from get_objc_protocols({}) on the original fixture:

{
  "count": 2,
  "protocols": [
    {"address": "0x100000818", "name": "-[Widget _TtPing]"},
    {"address": "0x1000008a0", "name": "_objc_msgSend$_TtPing"}
  ]
}

The renamed-selector control returned {"count":0,"protocols":[]}. The positive control returned {"count":1,"protocols":[{"address":"0x100008108","name":"__OBJC_PROTOCOL_$_LocalProtocol"}]}. Addresses can vary with compiler/build.

Typed outcome or recovery expected

A successful empty protocol inventory for the original fixture and the renamed-selector control, while retaining genuine Objective-C and Swift protocol labels. Checking genuine Swift protocol preservation is a proposed restoration check, not an executed result of this investigation.

Analysis or suspected cause

Source-derived reasoning: src/domain/symbolAnalysis.ts:44-63 accepts any name containing _TtP; both returned names satisfy that substring rule. src/application/EnhancedTools.ts:299-301 applies discovery to the provider's name inventory through the handler in src/server/registerEnhancedTools.ts:104-112.

The submitter fetched upstream origin/main at c2858d2aa0916f0dd2d073d848b8c2195d9bf6b3. The cited discovery rule, application workflow, and contract are unchanged from the reproduction baseline. The registration-file change only affects workflow snapshot recording; no later change in these paths plausibly fixes this behavior. This is source verification of upstream persistence, not a new runtime reproduction on main.

Additional context

Prepared with AI assistance and independently reproduced by a separate verifier.

Related but different: https://github.com/morluto/rea/issues/5576 concerns analyze_swift_types counting Objective-C labels as Swift observations. This report concerns the distinct get_objc_protocols tool returning them as protocol labels; either tool's defect can remain after the other is fixed. Issue #4383 and PRs #4405/#4408 concern direct-call input validation; closed PR #1315 concerns missing genuine Swift protocol descriptors. Closed #4540 / merged PR #4549 concern malformed protocol-method metadata recovery, not this inventory filter.

Regression range: NOT_ENOUGH_INFO; no last-known-good version was established.

Originally created by @coygeek on GitHub (Oct 20, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/5580 ### 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 On an Objective-C executable with no protocol declaration and no Swift source, MCP `get_objc_protocols` with `{}` returns `count: 2`: the method label `-[Widget _TtPing]` and its message-send shim `_objc_msgSend$_TtPing`. The independent verifier reproduced this through the production MCP server with `provider_id: "hopper"`; all open, analysis, and close calls succeeded. ### Reproduction The independent verifier compiled this reduced fixture against the source baseline below: ```sh mkdir -p repro cat > repro/widget.m <<'OBJC' #import <Foundation/Foundation.h> @interface Widget : NSObject - (void)_TtPing; @end @implementation Widget - (void)_TtPing { } @end int main(void) { [[[Widget alloc] init] _TtPing]; return 0; } OBJC clang -fobjc-arc -framework Foundation repro/widget.m -o repro/widget_protocol ``` 1. Start the built production server with `node scripts/rea.mjs mcp` using a stdio MCP client and initialize the connection. 2. Call `open_binary` with `{"path":"<absolute path to repro/widget_protocol>","provider_id":"hopper"}`. Resolve the fixture path with `python3 -c 'from pathlib import Path; print(Path("repro/widget_protocol").resolve())'`. 3. Call `get_objc_protocols` with `{}` and inspect `structuredContent.normalized_result`. 4. Call `close_binary` with `{}`. The verifier executed this sequence once for each of three separately compiled fixtures, closing each before opening the next. Renaming the selector to `TtPing` returned `{"count":0,"protocols":[]}`. A separate positive control declaring `@protocol LocalProtocol` and conforming `Widget` returned one genuine protocol label. The replay used isolated home/configuration directories; the server exited successfully. No new Hopper session was run during submission. ### Expected behavior Return `{"count":0,"protocols":[]}` for the original fixture, as for the renamed-selector control. A method implementation and a message-send shim are not protocol labels. `src/contracts/enhancedToolContracts.ts:39-41`, independently confirmed through production MCP `tools/list`, promises discovery and deduplication of Objective-C and Swift protocol labels. Genuine protocol labels must remain discoverable. ### Impact and scope The tested valid Objective-C input produces two false protocol inventory entries and an incorrect count. This is a bounded P2 impact assessment. Callers can discard the observed Objective-C method/shim forms and recompute the count; the verifier checked that workaround against all three captured results, retaining the genuine protocol control. Other providers, prevalence in ordinary binaries, and all Swift mangling forms were not tested. No security-boundary failure was observed. ### REA version 6.7.0; source commit `074768901f3cdc8205b61773fb1faf6f6c7b3ca8`. ### Runtime and platform macOS arm64; Hopper Disassembler 6.1.0-demo, selected explicitly. NOT_ENOUGH_INFO: the verifier did not record the exact Node.js version or macOS release. A licensed Hopper distribution was not tested. ### Target and artifact context Self-built arm64 Mach-O Objective-C executable linked against Foundation, with no protocol declaration or Swift source; selector-renamed negative control and genuine Objective-C protocol positive control. ### Interface MCP ### Earliest failure stage Native analysis or reconstruction ### Relevant output or evidence The independent verifier observed this `structuredContent.normalized_result` from `get_objc_protocols({})` on the original fixture: ```json { "count": 2, "protocols": [ {"address": "0x100000818", "name": "-[Widget _TtPing]"}, {"address": "0x1000008a0", "name": "_objc_msgSend$_TtPing"} ] } ``` The renamed-selector control returned `{"count":0,"protocols":[]}`. The positive control returned `{"count":1,"protocols":[{"address":"0x100008108","name":"__OBJC_PROTOCOL_$_LocalProtocol"}]}`. Addresses can vary with compiler/build. ### Typed outcome or recovery expected A successful empty protocol inventory for the original fixture and the renamed-selector control, while retaining genuine Objective-C and Swift protocol labels. Checking genuine Swift protocol preservation is a proposed restoration check, not an executed result of this investigation. ### Analysis or suspected cause Source-derived reasoning: `src/domain/symbolAnalysis.ts:44-63` accepts any name containing `_TtP`; both returned names satisfy that substring rule. `src/application/EnhancedTools.ts:299-301` applies discovery to the provider's name inventory through the handler in `src/server/registerEnhancedTools.ts:104-112`. The submitter fetched upstream `origin/main` at `c2858d2aa0916f0dd2d073d848b8c2195d9bf6b3`. The cited discovery rule, application workflow, and contract are unchanged from the reproduction baseline. The registration-file change only affects workflow snapshot recording; no later change in these paths plausibly fixes this behavior. This is source verification of upstream persistence, not a new runtime reproduction on main. ### Additional context Prepared with AI assistance and independently reproduced by a separate verifier. Related but different: https://github.com/morluto/rea/issues/5576 concerns `analyze_swift_types` counting Objective-C labels as Swift observations. This report concerns the distinct `get_objc_protocols` tool returning them as protocol labels; either tool's defect can remain after the other is fixed. Issue #4383 and PRs #4405/#4408 concern direct-call input validation; closed PR #1315 concerns missing genuine Swift protocol descriptors. Closed #4540 / merged PR #4549 concern malformed protocol-method metadata recovery, not this inventory filter. Regression range: NOT_ENOUGH_INFO; no last-known-good version was established.
Author
Owner

@matbrgz commented on GitHub (Oct 20, 2026):

Cross-referencing with canonical issue #5576 ([Bug] analyze_swift_types counts Objective-C labels containing _Tt as Swift observations) and sibling #5607. Both address lexical confusion between Objective-C labels and mangled Swift identifiers (_Tt, _TtP) in metadata extraction. Cataloged under Cluster BH in consolidation tracker #4330.

<!-- gh-comment-id:6295988609 --> @matbrgz commented on GitHub (Oct 20, 2026): Cross-referencing with canonical issue #5576 (`[Bug] analyze_swift_types counts Objective-C labels containing _Tt as Swift observations`) and sibling #5607. Both address lexical confusion between Objective-C labels and mangled Swift identifiers (`_Tt`, `_TtP`) in metadata extraction. Cataloged under Cluster BH in consolidation tracker #4330.
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#3390
No description provided.