Gem `BUNDLE_GEMFILE` check compares paths lexically, so a symlinked spelling of the project's own Gemfile (e.g. macOS `/tmp/app/Gemfile`) is refused, and `vex` / `rollback` reject the hosted patch Bundler is loading
I maintainer di solito rispondono entro 1 giorno
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 2/5
- Tempo stimato
- 1-3 ore
- Idoneità per principianti
- 85/100
Direzione di ricerca
Leggi crates/socket-patch-core/src/formats/gem/manifest.rs, iniziando dalla funzione resolve_against intorno alle righe 138-147 e dal confronto del manifest alle righe 183-189. La correzione dovrebbe canonicalizzare i percorsi (o usare l’identità del file) quando confronta BUNDLE_GEMFILE con la radice del progetto, in modo da accettare i percorsi con collegamenti simbolici che puntano allo stesso Gemfile. Il lavoro è completato quando funziona il caso di riproduzione nell’issue: BUNDLE_GEMFILE=$PWD/Gemfile su un progetto con collegamenti simbolici non restituisce più redirect_gem_bundle_gemfile_unsupported.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
[agent] Found by the scheduled Bundler (RubyGems) bug-hunt routine (ledger #316).
Summary
formats::gem::manifest::classify decides whether BUNDLE_GEMFILE names the project's own Gemfile / gems.rb by comparing std::path::absolute + normalize_lexically of the setting against the project root. It never resolves symlinks. The root comes from the process cwd (getcwd, the physical path) or --cwd. A shell's $PWD, and paths people type, are often the logical path through a symlink. So BUNDLE_GEMFILE=$PWD/Gemfile names the same file Bundler loads, but socket-patch classifies it as "another manifest" (LoadedManifest::Unsupported).
On macOS this is the default for anything under /tmp (→ /private/tmp) or $TMPDIR (/var/folders/… → /private/var/…). On Linux it hits any project reached through a symlinked directory (a symlinked workspace or home, /app → volume, and so on).
Impact
All of these fail closed, but each one stops socket-patch from working on a correctly configured project, with a message that's factually wrong:
- Hosted
scanredirects nothing:redirect_gem_bundle_gemfile_unsupported("bundler loads/tmp/bh-app/Gemfile… not the project's Gemfile or gems.rb"). That is the project's Gemfile. vexon an already-redirected project whose install is patched (Bundler loads the patched gem) refuses with exit 2: "BUNDLE_GEMFILE points bundler at another manifest, so this wiring is never installed and the patch is not attested". It also suggests deletingGemfile.lock, which is the lock Bundler uses.rollback/removeerror out withpatched_ref_unattributablefor the same reason, so the hosted patch can't be unwound while the variable is set.
The same function backs bundler_loaded_lock_in (lock inventory, ledger recovery, VEX discovery) and the vendored manifest check, so every gem lock reader inherits this.
Repro (Linux; the ln -s stands in for macOS /tmp)
mkdir -p real/app && ln -s "$PWD/real" link && cd link/app
printf 'source "https://rubygems.org"\n\ngem "colorize", "0.8.1"\ngem "rainbow"\n' > Gemfile
bundle config set --local path vendor/bundle && bundle install && bundle lock --add-checksums
echo "PWD=$PWD physical=$(pwd -P)"
BUNDLE_GEMFILE=$PWD/Gemfile bundle exec ruby -e 'puts Bundler.default_lockfile' # → link/app/Gemfile.lock (same file)
A="--api-url <mock> --org org --api-token fake --patch-server-url <mock>"
socket-patch scan --mode hosted --json --yes --dry-run $A # redirected: 1
BUNDLE_GEMFILE=$PWD/Gemfile socket-patch scan --mode hosted --json --yes --dry-run $A # redirected: 0, redirect_gem_bundle_gemfile_unsupported
BUNDLE_GEMFILE=$(pwd -P)/Gemfile socket-patch scan --mode hosted --json --yes --dry-run $A # redirected: 1
# after a real redirect (no env) + bundle install → installed gem is patched:
BUNDLE_GEMFILE=$PWD/Gemfile socket-patch vex --product pkg:gem/app@1 $A # exit 2 ("never installed")
BUNDLE_GEMFILE=$PWD/Gemfile socket-patch rollback --dry-run --json --yes $A # status error, patched_ref_unattributable
The same refusal happens for --cwd <symlinked path> with BUNDLE_GEMFILE=<physical path>, and for .bundle/config BUNDLE_GEMFILE: "<symlinked abs path>/Gemfile" (as written by bundle config set --local gemfile "$PWD/Gemfile"), with no environment variable at all.
Expected vs actual
- Expected, per docs/ecosystems.md (RubyGems row):
BUNDLE_GEMFILE"is followed when it names the project'sGemfile/gems.rb, and any other configured manifest is refused". Bundler expands the path and resolves it to the same file and the sameGemfile.lock(Bundler.default_lockfileabove), so socket-patch should treat it as the project'sGemfile. - Actual: the refusal fires when it shouldn't (a false
Unsupported), and the VEX / rollback messages claim Bundler uses a different manifest.
Matrix (Bundler 4.0.22)
| OS | Setup | Unset | BUNDLE_GEMFILE=$PWD/Gemfile (logical) |
BUNDLE_GEMFILE=$(pwd -P)/Gemfile |
|---|---|---|---|---|
| macos-latest, Ruby 3.4.9 | project in /tmp/bh-app (physical /private/tmp/bh-app) |
redirected 1 | refused | redirected 1 |
| ubuntu-latest, Ruby 3.4 | project via symlinked dir | redirected 1 | refused | redirected 1 |
| Linux sandbox, Ruby 3.3.6 | same, plus vex / rollback after a real redirect + install (2/2) |
vex ok | vex exit 2, rollback error (installed gem is patched) | — |
| Linux sandbox | --cwd <link> + env <real> / config abs <link> path |
— | refused / refused | — |
Probe run: https://github.com/SocketDev/socket-patch/actions/runs/37382646373 (the probe's own vex/rollback cells hit a stale vendor/bundle harness artifact; the Linux sandbox rows cover them).
First bad commit
9d718cf5 (#431, the fix for #341 / #390), which introduced the BUNDLE_GEMFILE classification with a lexical compare; cbf1f748 (#532) kept it. The v4.0.0 release binary ignores BUNDLE_GEMFILE and redirects this project (it predates the classification), so this hasn't shipped in a release yet.
Suspect code
crates/socket-patch-core/src/formats/gem/manifest.rs:138-147(resolve_against:absolute+normalize_lexicallyonly) and:183-189(target == root.join(manifest)).- The same lexical compare is in
env_keeps_root(manifest.rs:163-166), which decides whether the env var moves Bundler's root.
Comparing canonicalized paths (or file identity, same_file-style) whenever both exist would match what Bundler does. A lexical match could stay as the fast path, falling back to canonicalization only when it fails, so a symlinked Gemfile file (already refused elsewhere) keeps its own handling.
- Lingua principale
- Rust
- Stelle
- 8
- Fork
- 0
- Merge medio
- 1g 7m
- PR unite (30g)
- 178
Preparare l'ambiente
- Nessun Dockerfile né file Docker Compose
- Nessun modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di SocketDev/socket-patch
-
Hosted yarn classic pins give no berry-migration warning, so a yarn 2+ install silently drops them (vendored warns about the same trap)Forse già presa @mikolalysenko l’ha presa oggi. Apertaagent:claimed agent:triaged bug bughunt pm:yarn-classic priority:p1
Difficoltà 2/5 1-3 ore Idoneità per principianti 85/100
SocketDev/socket-patch#907 · 2 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
agent:triaged bug bughunt pm:npm priority:p1
Difficoltà 2/5 1-3 ore Idoneità per principianti 75/100
SocketDev/socket-patch#900 ·
I maintainer di solito rispondono entro 1 giorno
-
agent:triaged bug bughunt pm:yarn-berry priority:p1
Difficoltà 2/5 1-3 ore Idoneità per principianti 73/100
SocketDev/socket-patch#783 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
agent:triaged bug bughunt pm:pipenv priority:p1
Difficoltà 2/5 1-3 ore Idoneità per principianti 83/100
SocketDev/socket-patch#744 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
agent:triaged bug bughunt pm:cargo priority:p2
Difficoltà 2/5 1-3 ore Idoneità per principianti 84/100
SocketDev/socket-patch#651 · 3 commenti ·
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di SocketDev/socket-patch
Issue simili
-
bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 85/100
wardian-app/Wardian#1603 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 70/100
I maintainer di solito rispondono entro 2 giorni
-
bug
Difficoltà 1/5 1-3 ore Idoneità per principianti 72/100
peteonrails/voxtype#844 ·
I maintainer di solito rispondono entro 1 giorno
-
feature
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 85/100
uwuclxdy/clauth#107 · 1 commento ·
I maintainer di solito rispondono entro 4 giorni