Skip to content

feat: normalize /sdcard paths to device canonical external storage#558

Draft
djbclark wants to merge 2 commits into
SuperMonster003:masterfrom
djbclark:pr/path-normalization
Draft

feat: normalize /sdcard paths to device canonical external storage#558
djbclark wants to merge 2 commits into
SuperMonster003:masterfrom
djbclark:pr/path-normalization

Conversation

@djbclark

@djbclark djbclark commented Jul 14, 2026

Copy link
Copy Markdown

On standard Android, /sdcard is a symlink to /storage/emulated/0, so File("/sdcard/...").exists() works. On some devices (Fire OS, some custom ROMs), this symlink doesn't exist — Environment.getExternalStorageDirectory() returns a different canonical path.

This PR adds EnvironmentUtils.normalizePath() which:

  1. Checks File(path).exists() first — returns original path unchanged if valid (no-op on standard Android)
  2. Replaces /sdcard/ and /mnt/sdcard/ prefixes with Environment.getExternalStorageDirectory()
  3. Verifies the normalized path exists before returning it — falls back to original otherwise

Applied in ScriptIntents.kt so scripts launched via am start -d file:///sdcard/... from external tools work correctly on all devices.

Two utility files changed, 29 lines added.


Security update: normalizePath() now resolves .. traversal components by calling File.canonicalPath on existing paths, wrapped in try-catch for robustness.

djbclark added 2 commits July 14, 2026 00:16
ScriptIntents now normalizes /sdcard/ and /mnt/sdcard/ path prefixes to
Environment.getExternalStorageDirectory() when the file doesn't exist at
the given path. This is a no-op on standard Android (where /sdcard is a
symlink) but fixes script execution on devices without the symlink
(Fire OS, some custom ROMs).

EnvironmentUtils.normalizePath() checks File(path).exists() first to
avoid unnecessary remapping on devices where the given path is valid.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant