[GH-ISSUE #6527] [Bug] start-adb-activity rejects nested activity component names #3919

Closed
opened 2026-10-31 00:45:14 +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/6527

Before submitting

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

Area

Other

Observed behavior

Source-only finding: start_adb_activity rejects valid explicit Android component names containing $, such as com.example/.Outer$InnerActivity. Its component regular expression admits only ASCII letters, digits, ., _, and - on either side of /. A nested activity's binary class name cannot pass this schema, so REA refuses the request before contacting ADB.

No runtime reproduction was performed. This finding concerns ADB intent-component admission, rather than the JADX class/method resolver covered by #6398.

Reproduction

Proposed, not run:

  1. On a connected test device, use an installed app that declares an exported, public static nested activity com.example.Outer$InnerActivity.
  2. Call MCP start_adb_activity with:
{"serial":"emulator-5554","action":"android.intent.action.MAIN","component":"com.example/.Outer$InnerActivity"}
  1. The source-derived result is an input-validation failure on component, before provider execution. As a control, the same request with com.example/.MainActivity satisfies the component pattern.

NOT_ENOUGH_INFO: no APK, device, REA invocation, or direct-ADB control was run; the proposed target is illustrative.

Expected behavior

Preserve a valid caller-selected component and pass it as the -n operand. The REA tool contract exposes an optional explicit component without limiting it to top-level activity classes. Android's ComponentName constructor obtains a component class name through Class.getName(), and unflattenFromString preserves the class portion and expands a leading dot. Nested binary class names containing $ therefore fit the platform's component representation.

Impact and scope

Explicit launches of activities whose class names contain $ are blocked through REA's shared CLI/MCP request schema. This prevents selecting such a non-launcher activity even when its component is known. The issue is bounded to the admitted component alphabet; it does not establish a failure for ordinary top-level activity names.

A practical source-supported bypass is to issue the same intent directly with ADB, preserving the action and component. That bypass was not executed here, so its runtime availability is unverified. Frequency across real applications is NOT_ENOUGH_INFO.

REA version

Audited source: main commit 49c9c9d4a14cc7d5509ec28a304dab48f85cb045. Its package metadata says 6.7.0. The same component pattern exists in tag rea-agents-6.7.0, commit 27dc42d10249f0410904a75c0997842eb03b931c; this is a tagged-source observation, not a claim that the published package was tested.

Runtime and platform

NOT_ENOUGH_INFO: no REA runtime or ADB/device execution was performed. Android 15 source supplies the component-format reference; behavior on an actual device remains untested.

Target and artifact context

Illustrative Android application with an exported public static nested activity declared by binary class name, for example com.example.Outer$InnerActivity. No target artifact was acquired or executed.

Interface

MCP

Earliest failure stage

Request parsing or validation

Relevant output or evidence

Obtained by reading the exact source revision; no runtime output is claimed.

.regex(
  /^[A-Za-z0-9._\x2d]+(\/[A-Za-z0-9._\x2d]*)?$/u,
  "Component must be package/activity form",
)

Additional context

The supplied open-issue inventory was searched for component, activity, dollar/inner-class, and start_adb_activity reports. #6398 concerns a different JADX class/method selection path; #5093 concerns empty string extras. Neither is the component-pattern root cause described here. Final live searches of open and closed issues found no matching report.

Triage assessment

  • Impact level: P2
  • Assessment status: provisional
  • Impact basis: The source schema deterministically excludes nested activity component names before ADB dispatch, blocking a bounded set of explicit activity-selection requests. No runtime reproduction or real-app frequency was established.
  • Workaround status: unverified
  • Workaround basis: Direct ADB can express the same action and component without REA's pattern, and Android's component parser preserves the name. No connected-device control was run to verify that bypass for an affected app.
Originally created by @coygeek on GitHub (Oct 23, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/6527 ### 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 Other ### Observed behavior Source-only finding: `start_adb_activity` rejects valid explicit Android component names containing `$`, such as `com.example/.Outer$InnerActivity`. Its component regular expression admits only ASCII letters, digits, `.`, `_`, and `-` on either side of `/`. A nested activity's binary class name cannot pass this schema, so REA refuses the request before contacting ADB. No runtime reproduction was performed. This finding concerns ADB intent-component admission, rather than the JADX class/method resolver covered by #6398. ### Reproduction Proposed, not run: 1. On a connected test device, use an installed app that declares an exported, public static nested activity `com.example.Outer$InnerActivity`. 2. Call MCP `start_adb_activity` with: ```json {"serial":"emulator-5554","action":"android.intent.action.MAIN","component":"com.example/.Outer$InnerActivity"} ``` 3. The source-derived result is an input-validation failure on `component`, before provider execution. As a control, the same request with `com.example/.MainActivity` satisfies the component pattern. NOT_ENOUGH_INFO: no APK, device, REA invocation, or direct-ADB control was run; the proposed target is illustrative. ### Expected behavior Preserve a valid caller-selected component and pass it as the `-n` operand. The [REA tool contract](https://github.com/morluto/rea/blob/49c9c9d4a14cc7d5509ec28a304dab48f85cb045/src/contracts/adb/adbToolContracts.ts#L340-L347) exposes an optional explicit component without limiting it to top-level activity classes. Android's [ComponentName constructor](https://github.com/aosp-mirror/platform_frameworks_base/blob/4e43ad12e1b211f15152e9c5b16b0fe88e6b93f3/core/java/android/content/ComponentName.java#L132-L135) obtains a component class name through `Class.getName()`, and [unflattenFromString](https://github.com/aosp-mirror/platform_frameworks_base/blob/4e43ad12e1b211f15152e9c5b16b0fe88e6b93f3/core/java/android/content/ComponentName.java#L276-L286) preserves the class portion and expands a leading dot. Nested binary class names containing `$` therefore fit the platform's component representation. ### Impact and scope Explicit launches of activities whose class names contain `$` are blocked through REA's shared CLI/MCP request schema. This prevents selecting such a non-launcher activity even when its component is known. The issue is bounded to the admitted component alphabet; it does not establish a failure for ordinary top-level activity names. A practical source-supported bypass is to issue the same intent directly with ADB, preserving the action and component. That bypass was not executed here, so its runtime availability is unverified. Frequency across real applications is NOT_ENOUGH_INFO. ### REA version Audited source: main commit `49c9c9d4a14cc7d5509ec28a304dab48f85cb045`. Its package metadata says 6.7.0. The same component pattern exists in tag `rea-agents-6.7.0`, commit `27dc42d10249f0410904a75c0997842eb03b931c`; this is a tagged-source observation, not a claim that the published package was tested. ### Runtime and platform NOT_ENOUGH_INFO: no REA runtime or ADB/device execution was performed. Android 15 source supplies the component-format reference; behavior on an actual device remains untested. ### Target and artifact context Illustrative Android application with an exported public static nested activity declared by binary class name, for example `com.example.Outer$InnerActivity`. No target artifact was acquired or executed. ### Interface MCP ### Earliest failure stage Request parsing or validation ### Relevant output or evidence Obtained by reading the exact source revision; no runtime output is claimed. - [Component schema](https://github.com/morluto/rea/blob/49c9c9d4a14cc7d5509ec28a304dab48f85cb045/src/domain/adb/adbDeviceAnalysis.ts#L317-L326): ```ts .regex( /^[A-Za-z0-9._\x2d]+(\/[A-Za-z0-9._\x2d]*)?$/u, "Component must be package/activity form", ) ``` - [Shared admission](https://github.com/morluto/rea/blob/49c9c9d4a14cc7d5509ec28a304dab48f85cb045/src/application/ProviderOperationExecution.ts#L58-L79) validates the request before `provider.execute`. - [ADB argument construction](https://github.com/morluto/rea/blob/49c9c9d4a14cc7d5509ec28a304dab48f85cb045/src/adb/AdbProvider.ts#L2806-L2814) already forwards the chosen component as `-n`; [remote-shell operand quoting](https://github.com/morluto/rea/blob/49c9c9d4a14cc7d5509ec28a304dab48f85cb045/src/adb/AdbCommand.ts#L70-L84) preserves characters outside its unquoted alphabet. The refusal occurs earlier in the schema. - [Tagged source](https://github.com/morluto/rea/blob/27dc42d10249f0410904a75c0997842eb03b931c/src/domain/adb/adbDeviceAnalysis.ts#L274-L283) contains the same component pattern. ### Additional context The supplied open-issue inventory was searched for component, activity, dollar/inner-class, and `start_adb_activity` reports. #6398 concerns a different JADX class/method selection path; #5093 concerns empty string extras. Neither is the component-pattern root cause described here. Final live searches of open and closed issues found no matching report. ## Triage assessment - Impact level: P2 - Assessment status: provisional - Impact basis: The source schema deterministically excludes nested activity component names before ADB dispatch, blocking a bounded set of explicit activity-selection requests. No runtime reproduction or real-app frequency was established. - Workaround status: unverified - Workaround basis: Direct ADB can express the same action and component without REA's pattern, and Android's component parser preserves the name. No connected-device control was run to verify that bypass for an affected app.
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#3919
No description provided.