Hacktoberfest 2026: as issues que os mantenedores marcaram para outubro, abertas e boas para iniciantes. Ver issues do Hacktoberfest

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

Aberta Para iniciantes
#896 1 comentário 0 reações 0 responsáveis Ver no GitHub

Mantenedores costumam responder em até 1 dia

Ninguém assumiu esta issue ainda.

Avaliação

Dificuldade
2/5
Tempo estimado
1-3 horas
Facilidade para iniciantes
85/100
Tipo de issue
Bug
Clareza
Claramente especificada
Status de atividade
Ativa
Stack de tecnologia
ruby, rust
Domínio
cli

Direção de pesquisa

Leia crates/socket-patch-core/src/formats/gem/manifest.rs, começando pela função resolve_against por volta das linhas 138-147 e pela comparação do manifesto nas linhas 183-189. A correção deve canonicalizar os caminhos (ou usar a identidade do arquivo) ao comparar BUNDLE_GEMFILE com a raiz do projeto, para que caminhos com links simbólicos para o mesmo Gemfile sejam aceitos. O trabalho estará concluído quando o caso de reprodução do issue funcionar: BUNDLE_GEMFILE=$PWD/Gemfile em um projeto com links simbólicos não retorna mais redirect_gem_bundle_gemfile_unsupported.

Escrita pelo modelo de indexação a partir do texto da issue.

Descrição

agent:triaged bug bughunt pm:bundler priority:p1

[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 scan redirects 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.
  • vex on 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 deleting Gemfile.lock, which is the lock Bundler uses.
  • rollback / remove error out with patched_ref_unattributable for 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's Gemfile / gems.rb, and any other configured manifest is refused". Bundler expands the path and resolves it to the same file and the same Gemfile.lock (Bundler.default_lockfile above), so socket-patch should treat it as the project's Gemfile.
  • 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_lexically only) 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.

Linguagem predominante
Rust
Estrelas
8
Forks
0
Merge médio
19h 21min
PRs com merge (30d)
421

Preparar o ambiente

Primeiros passos

  1. Leia a issue inteira e depois o guia de contribuição do projeto.
  2. Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
  3. Faça um fork do repositório e trabalhe em uma branch.
  4. Abra um pull request que referencie o número da issue.

Mais de SocketDev/socket-patch

Todas as issues de SocketDev/socket-patch

Issues semelhantes

Mais issues de Rust

Receba novas issues na sua caixa de entrada

Um resumo curto de issues do GitHub para quem está começando.