Hacktoberfest 2026: những issue maintainer đã đánh dấu cho tháng Mười, đang mở và phù hợp người mới. Xem issue 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

Đang mở Phù hợp với người mới
#896 1 bình luận 0 reaction 0 người được giao Xem trên GitHub

Maintainer thường phản hồi trong vòng 1 ngày

Chưa có ai nhận issue này.

Đánh giá

Độ khó
2/5
Thời gian dự kiến
1-3 giờ
Mức phù hợp với người mới
85/100
Loại issue
Lỗi
Độ rõ ràng
Đặc tả rõ ràng
Mức độ hoạt động
Sôi nổi
Công nghệ
ruby, rust
Lĩnh vực
cli

Hướng nghiên cứu

Đọc crates/socket-patch-core/src/formats/gem/manifest.rs, bắt đầu từ hàm resolve_against quanh dòng 138-147 và phần so sánh manifest ở dòng 183-189. Bản sửa nên chuẩn hóa đường dẫn (hoặc dùng danh tính tệp) khi so sánh BUNDLE_GEMFILE với thư mục gốc của dự án, để chấp nhận các đường dẫn liên kết tượng trưng trỏ đến cùng một Gemfile. Công việc được xem là hoàn tất khi trường hợp tái hiện trong issue hoạt động: BUNDLE_GEMFILE=$PWD/Gemfile trên một dự án có liên kết tượng trưng không còn trả về redirect_gem_bundle_gemfile_unsupported.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

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.

Ngôn ngữ chính
Rust
Star
8
Fork
0
Merge trung bình
1 ngày 1 giờ
Pull request đã merge (30 ngày)
211

Chuẩn bị môi trường

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của SocketDev/socket-patch

Tất cả issue của SocketDev/socket-patch

Issue tương tự

Thêm issue về Rust

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.