Repository navigation
fix(http): make raw executables readable, not just executable - #11135
Conversation
make_executable only added the execute bits (mode | 0o111), so a downloaded tempfile created with 0o600 ended up 0o711. For system-wide installs owned by root this left interpreted executables (e.g. PHP PHARs like Composer) executable but not readable by non-owner users, causing "Could not open input file". Add the matching read bits alongside execute so any class that gains execute also gains read. Fixes #11108 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
📝 WalkthroughWalkthroughUnix executable handling now adds corresponding read bits when granting execute permissions. Both synchronous and asynchronous paths use the shared mode calculation, with Unix-only tests covering representative permission modes. ChangesUnix executable permissions
Estimated code review effort: 2 (Simple) | ~10 minutes Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Greptile SummaryFixes a real-world failure where downloaded raw executables (e.g. PHP PHARs) were left with mode
Confidence Score: 5/5Safe to merge — tiny, well-tested permission arithmetic that strictly expands readability without touching write bits, fixing a documented runtime failure with no regressions on the existing call sites. The change is a two-line mode computation ( No files require special attention. Important Files Changed
Reviews (3): Last reviewed commit: "Revert "refactor(http): use async metada..." | Re-trigger Greptile |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/file.rs`:
- Around line 766-768: Update the permission-setting flow around path.metadata()
to retrieve metadata through Tokio’s asynchronous filesystem API instead of the
synchronous std::fs operation. Preserve the existing permissions mutation via
executable_mode and the subsequent tokio::fs::set_permissions call.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Central YAML (base), Organization UI (inherited)
Review profile: CHILL
Plan: Pro Plus
Run ID: 586dd1ee-5bd4-4893-909b-a2bf132eae23
📒 Files selected for processing (1)
src/file.rs
make_executable_async is async and already uses tokio::fs::set_permissions, so read metadata via tokio::fs::metadata rather than the blocking std variant. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This reverts commit 01d0044.
Hyperfine Performance
|
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.7.7 x -- echo |
23.7 ± 1.7 | 19.2 | 30.8 | 1.02 ± 0.11 |
mise x -- echo |
23.2 ± 1.8 | 18.7 | 31.3 | 1.00 |
mise env
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.7.7 env |
23.4 ± 1.7 | 19.4 | 29.8 | 1.03 ± 0.11 |
mise env |
22.8 ± 1.8 | 18.2 | 29.6 | 1.00 |
mise hook-env
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.7.7 hook-env |
25.7 ± 1.9 | 20.5 | 30.9 | 1.03 ± 0.13 |
mise hook-env |
24.9 ± 2.5 | 18.8 | 35.8 | 1.00 |
mise ls
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.7.7 ls |
21.9 ± 2.0 | 17.4 | 29.7 | 1.05 ± 0.15 |
mise ls |
20.7 ± 2.3 | 15.8 | 29.6 | 1.00 |
xtasks/test/perf
| Command | mise-2026.7.7 | mise | Variance |
|---|---|---|---|
| install (cached) | 180ms | 176ms | +2% |
| ls (cached) | 72ms | 73ms | -1% |
| bin-paths (cached) | 71ms | 71ms | +0% |
| task-ls (cached) | 139ms | 139ms | +0% |
Problem
Reported in #11108. When a raw executable (e.g. a PHP PHAR like Composer) is installed via the HTTP backend, mise creates it with mode
0711instead of0755.file::make_executableonly added the execute bits:The downloaded tempfile is created with restrictive perms (
0600), so after+xit becomes0711— executable by everyone but readable only by the owner. For system-wide installs owned by root, a non-owner user can execute the file but the interpreter (PHP) can't read the PHAR, so:This affects both the raw-file and decompressed-raw-file paths in
src/backend/http.rs.Fix
Add the matching read bits alongside the execute bits, so any class that gains execute also gains read (
mode | 0o111 | 0o444). Existing write bits are preserved; an already-0755file is unchanged.This is applied in the shared
make_executable/make_executable_asynchelpers, so it hardens the invariant "executable ⇒ readable" everywhere, not just the HTTP backend.Test
Added a unit test covering the mode transformation (
0o600 → 0o755,0o640 → 0o755,0o660 → 0o775,0o755unchanged).Fixes #11108
Note
Low Risk
Small, localized Unix permission logic with unit tests; broad call sites only widen read on paths already being marked executable.
Overview
Fixes interpreted executables (e.g. PHP PHARs from the HTTP backend) that were left executable but not world-readable when installs started from restrictive temp modes like
0600(0711afterchmod +x).On Unix,
make_executableandmake_executable_asyncnow set modes via a sharedexecutable_modehelper that appliesmode | 0o111 | 0o444, so any class that gains execute also gains the matching read bits while preserving existing write bits; modes that are already correct (e.g.0755) stay unchanged.Adds a
test_executable_mode_adds_read_with_executeunit test for the mode mapping (600/640→755,660→775, etc.).Reviewed by Cursor Bugbot for commit f1331ec. Bugbot is set up for automated code reviews on this repo. Configure here.
Summary by CodeRabbit