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
Les mainteneurs répondent en général sous 1 jour
Personne n'a encore pris cette issue.
Évaluation
- Difficulté
- 2/5
- Temps estimé
- 1-3 heures
- Accessibilité débutants
- 85/100
Piste de recherche
Lisez crates/socket-patch-core/src/formats/gem/manifest.rs en commençant par la fonction resolve_against autour des lignes 138-147 et la comparaison du manifeste aux lignes 183-189. La correction doit canonicaliser les chemins (ou utiliser l’identité du fichier) lors de la comparaison de BUNDLE_GEMFILE avec la racine du projet, afin que les chemins avec des liens symboliques vers le même Gemfile soient acceptés. Le travail est terminé lorsque le cas de reproduction de l’issue fonctionne : BUNDLE_GEMFILE=$PWD/Gemfile sur un projet avec des liens symboliques ne renvoie plus redirect_gem_bundle_gemfile_unsupported.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Description
[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.
- Langage dominant
- Rust
- Étoiles
- 8
- Forks
- 0
- Merge moyen
- 1 j 7 min
- PR mergées (30 j)
- 178
Préparer son environnement
- Aucun Dockerfile ni fichier Docker Compose
- Aucun modèle de pull request
- Lire le guide de contribution
Par où commencer
- Lisez l'issue en entier, puis le guide de contribution du projet.
- Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
- Forkez le dépôt et travaillez sur une branche.
- Ouvrez une pull request qui référence le numéro de l'issue.
Autres issues de 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)Peut-être pris @mikolalysenko l’a pris aujourd’hui. Ouverteagent:claimed agent:triaged bug bughunt pm:yarn-classic priority:p1
Difficulté 2/5 1-3 heures Accessibilité débutants 85/100
SocketDev/socket-patch#907 · 2 commentaires ·
Les mainteneurs répondent en général sous 1 jour
-
agent:triaged bug bughunt pm:npm priority:p1
Difficulté 2/5 1-3 heures Accessibilité débutants 75/100
SocketDev/socket-patch#900 ·
Les mainteneurs répondent en général sous 1 jour
-
agent:triaged bug bughunt pm:yarn-berry priority:p1
Difficulté 2/5 1-3 heures Accessibilité débutants 73/100
SocketDev/socket-patch#783 · 1 commentaire ·
Les mainteneurs répondent en général sous 1 jour
-
agent:triaged bug bughunt pm:pipenv priority:p1
Difficulté 2/5 1-3 heures Accessibilité débutants 83/100
SocketDev/socket-patch#744 · 1 commentaire ·
Les mainteneurs répondent en général sous 1 jour
-
agent:triaged bug bughunt pm:cargo priority:p2
Difficulté 2/5 1-3 heures Accessibilité débutants 84/100
SocketDev/socket-patch#651 · 3 commentaires ·
Les mainteneurs répondent en général sous 1 jour
Toutes les issues de SocketDev/socket-patch
Issues similaires
-
Difficulté 1/5 Moins d'une heure Accessibilité débutants 80/100
Devolutions/picky-rs#546 · 1 commentaire ·
Les mainteneurs répondent en général sous 3 jours
-
Difficulté 2/5 1-3 heures Accessibilité débutants 74/100
Les mainteneurs répondent en général sous 1 jour
-
enhancement
Difficulté 2/5 1-3 heures Accessibilité débutants 78/100
zcashlabs/thus-spoke-zakura#153 ·
Les mainteneurs répondent en général sous 1 jour
-
claude_code: step fails on session-scoped (`@inline`) plugins with `Invalid scope "session"`Ouverte
Difficulté 2/5 1-3 heures Accessibilité débutants 79/100
topgrade-rs/topgrade#2395 ·
Les mainteneurs répondent en général sous 1 jour
-
app bug windows-os
Difficulté 2/5 1-3 heures Accessibilité débutants 67/100
Les mainteneurs répondent en général sous 1 jour