Fix Termux permission gating before first send#110
Conversation
There was a problem hiding this comment.
Review Summary
This PR improves Termux permission checking by adding a dedicated hasTermuxRunCommandPermission() helper that verifies both runtime permission state and package permission grant flags. The approach addresses scenarios where the runtime check alone could incorrectly report granted status on certain devices/ROMs.
Critical Issue Found
Logic Error (Line 207): The bounds check fallback returns runtimeGranted when the flags array is unexpectedly short, which undermines the hardening intent. This should return false to deny permission when PackageInfo state appears corrupted or inconsistent, ensuring the permission flow executes as expected.
Once the logic error is fixed, the implementation will correctly enforce the two-part verification and prevent bypassing the permission dialog flow.
You can now have the agent implement changes and create commits directly on your pull request's source branch. Simply comment with /q followed by your request in natural language to ask the agent to make changes.
| val permissions = packageInfo.requestedPermissions ?: return@runCatching runtimeGranted | ||
| val flags = packageInfo.requestedPermissionsFlags ?: return@runCatching runtimeGranted | ||
| val index = permissions.indexOf("com.termux.permission.RUN_COMMAND") | ||
| if (index == -1 || index >= flags.size) runtimeGranted |
There was a problem hiding this comment.
🛑 Logic Error: The index bounds check on line 207 allows the function to return runtimeGranted when index >= flags.size, but this creates a logic flaw. If the permission exists in requestedPermissions at position index but flags array is too short, the code assumes the runtime permission check alone is sufficient. However, this bypasses the intended hardening that verifies both runtime permission state AND the grant flags. When flags array is unexpectedly shorter than permissions array (indicating a corrupted or inconsistent PackageInfo state), the function should treat this as a permission denial rather than falling back to the potentially incorrect runtime check that the PR aims to fix.
| if (index == -1 || index >= flags.size) runtimeGranted | |
| if (index == -1 || index >= flags.size) false |
Summary
com.termux.permission.RUN_COMMANDcheck inPhotoReasoningScreenbefore sending the first user messagehasTermuxRunCommandPermission()helper that verifies both:ContextCompat.checkSelfPermissionrequestedPermissionsFlags) fromPackageInfoWhy
The prior check could incorrectly behave as granted in some device/ROM scenarios, causing Screen Operator to proceed as if Termux access existed and skip the expected permission flow.
Validation
./gradlew :app:compileDebugKotlinsuccessfully.Codex Task