Hosted gem scan ignores a Gemfile `lockfile "custom.lock"` DSL call (Bundler 4), so it pins the unused Gemfile.lock, leaves the real lock untouched, and every frozen install fails
Mantenedores costumam responder em até 1 dia
Avaliação
- Dificuldade
- 4/5
- Tempo estimado
- 3-5 dias
- Facilidade para iniciantes
- 35/100
Direção de pesquisa
Start with crates/socket-patch-core/src/formats/gem/manifest.rs, especially LoadedManifest::with_lockfile and LoadedManifest::pair, and trace how the hosted engine reads Gemfile lockfile settings. Check crates/socket-patch-core/src/vendor/gem.rs and the existing Bundler 4 custom lockfile tests for the related vendored path. Add coverage for a Gemfile lockfile DSL call; done means hosted scans either refuse it without writing files or pin the lock Bundler actually uses, and frozen install succeeds.
Escrita pelo modelo de indexação a partir do texto da issue.
Descrição
[agent] Found by the scheduled Bundler (RubyGems) bug-hunt routine (ledger #316).
Summary
Bundler 4 has four ways to name a custom lockfile: BUNDLE_LOCKFILE in the env, the app config or the global config, plus a lockfile "<path>" call in the Gemfile itself. #768 (closing #749) refuses the three config/env spellings with redirect_gem_bundle_lockfile_unsupported. Nothing reads the Gemfile DSL spelling. With a Gemfile that starts with lockfile "custom.lock", scan --mode hosted:
- rewrites the
Gemfile(adds the patch-registrysource … doblock), - pins the leftover
Gemfile.lock, which Bundler no longer reads, - leaves
custom.lock, the lock Bundler actually reads, byte-untouched, - reports no
redirect_gem_bundle_lockfile_unsupported(or any lockfile) warning.
The next BUNDLE_FROZEN=true / deployment bundle install then fails: "The list of sources changed, but the lockfile can't be updated because frozen mode is set". The same project installs frozen without trouble before the scan.
The previous bug-hunt run posted this gap as a comment on the closed #749 (2026-10-08, main 823810a). It still reproduces on main 15c2c83, so this issue tracks it on its own.
Impact
CI and production installs (frozen or deployment) of a Bundler 4 project that uses the lockfile DSL break after a hosted scan. In the #749 comment's shape (no pre-existing install), the scan also exits 0 and the in-run --vex attests not_affected for a lock that was never pinned.
Repro
I used a scratch copy of crates/socket-patch-cli/tests/e2e_redirect_gem_build.rs, gem_hosted_bundler4_custom_lockfile_redirects_nothing. In the ScanVexCustomLockfile setup, I replaced bundle config set --local lockfile custom.lock with prepending lockfile "custom.lock"\n to the Gemfile. custom.lock is a copy of the pristine lock, and Gemfile.lock is left behind, exactly as in the existing test. I replaced the assertions with prints, then ran:
SOCKET_PATCH_BUNDLER_E2E_REQUIRED=1 cargo test -p socket-patch-cli --test <scratch copy> -- \
gem_hosted_bundler4_custom_lockfile_redirects_nothing --include-ignored --nocapture
- Pristine project with the DSL line:
BUNDLE_FROZEN=true bundle installexits 0. scan --mode hosted --json --vex …producessummary.applied: 1. Its warnings are onlyredirect_gem_stale_installandvex_omitted(this harness pre-installs intovendor/bundle), and there is noredirect_gem_bundle_lockfile_unsupported.GemfileandGemfile.lockare rewritten (Gemfile.locknow has the patch-registryGEMsection,vuln-gem (= 1.0.0)!and the patched sha256).custom.lockis unchanged (upstream remote,DEPENDENCIES vuln-gem, upstream sha256).- The frozen install afterwards fails:
The list of sources changed, but the lockfile can't be updated because frozen
mode is set
You have added to the Gemfile:
* vuln-gem (= 1.0.0)
You have deleted from the Gemfile:
* vuln-gem
You have changed in the Gemfile:
* vuln-gem from `no specified source` to `rubygems repository http://127.0.0.1:…/patch-registry/gem/…/`
Expected vs actual
- Expected: docs/ecosystems.md (RubyGems row) says "bundler 4's
BUNDLE_LOCKFILE… naming any other lock is refused withredirect_gem_bundle_lockfile_unsupported", and #749's contract is that the scan refuses, writes nothing and still installs frozen. Bundler'sDsl#to_definitionlets the Gemfilelockfilecall override the CLI/config lock (lockfile = @lockfile unless @lockfile.nil?, bundler 4.0.18lib/bundler/dsl.rb:193), so the DSL spelling should get the same refusal, or the scan should pin the lock it names. - Actual: the wrong lock is pinned with no warning, and frozen installs break.
Matrix (Linux, Ruby 3.3.6)
| Bundler | main | Lockfile spelling | Refused | custom.lock pinned |
Frozen install after scan |
|---|---|---|---|---|---|
| 4.0.22 | 15c2c83 |
Gemfile DSL lockfile "custom.lock" |
no (×2) | no | fails |
| 4.0.18 | 15c2c83 |
Gemfile DSL | no | no | fails |
| 4.0.18 | 823810a |
Gemfile DSL, no prior install (#749 comment) | no | no | fails, exit 16; in-run VEX attests |
| 4.0.x | 15c2c83 |
.bundle/config / env / global BUNDLE_LOCKFILE |
yes (existing test) | n/a | passes |
| < 4.0 | — | n/a (the DSL method doesn't exist) | — | — | — |
macOS and Windows weren't probed. The logic is OS-independent.
Suspect code
LoadedManifest::with_lockfile (crates/socket-patch-core/src/formats/gem/manifest.rs:183) only receives BUNDLE_LOCKFILE from env, app config and global config (manifest.rs:262 reads the config key). No gem reader parses a top-level lockfile call in the Gemfile / gems.rb, so the hosted engine falls through to the default Gemfile.lock pair (LoadedManifest::pair). The vendored path (crates/socket-patch-core/src/vendor/gem.rs, a_bundler4_custom_lockfile_is_refused) is probably affected the same way. I didn't verify it this run. lockfile false (Bundler writes no lock) is a related, untested shape.
- Linguagem predominante
- Rust
- Estrelas
- 8
- Forks
- 1
- Merge médio
- 17h 5min
- PRs com merge (30d)
- 557
Preparar o ambiente
- Sem Dockerfile nem arquivo Docker Compose
- Sem modelo de pull request
- Ler o guia de contribuição
Primeiros passos
- Leia a issue inteira e depois o guia de contribuição do projeto.
- Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
- Faça um fork do repositório e trabalhe em uma branch.
- Abra um pull request que referencie o número da issue.
Mais de SocketDev/socket-patch
-
agent:triaged bug bughunt pm:npm priority:p3 ux
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 75/100
SocketDev/socket-patch#1072 · 2 comentários ·
Mantenedores costumam responder em até 1 dia
-
agent:triaged bug bughunt pm:yarn-berry priority:p1
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 73/100
SocketDev/socket-patch#783 · 1 comentário ·
Mantenedores costumam responder em até 1 dia
-
Vendored cargo warns cargo_multi_version_old_cargo ("declares no rust-version") when the root package inherits rust-version from [workspace.package]Talvez já em andamento Um pull request vinculado a esta issue está aberto ou já foi mesclado. Abertaagent:triaged bug bughunt pm:cargo priority:p2
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 84/100
SocketDev/socket-patch#651 · 3 comentários ·
Mantenedores costumam responder em até 1 dia
-
bug bughunt pm:npm
Dificuldade 4/5 1-2 dias Facilidade para iniciantes 45/100
SocketDev/socket-patch#1534 ·
Mantenedores costumam responder em até 1 dia
-
agent:triaged bug bughunt pm:bundler priority:p1
Dificuldade 4/5 3-5 dias Facilidade para iniciantes 35/100
SocketDev/socket-patch#1531 · 1 comentário ·
Mantenedores costumam responder em até 1 dia
Todas as issues de SocketDev/socket-patch
Issues semelhantes
-
agent:iq3-xxs area: cli duplication enhancement priority: P3 ready-for-agent
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 72/100
Mantenedores costumam responder em até 1 dia
-
Dificuldade 1/5 Menos de uma hora Facilidade para iniciantes 85/100
Mantenedores costumam responder em até 2 dias
-
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 68/100
bytecodealliance/rustix#1703 ·
Mantenedores costumam responder em até 3 dias
-
bug discussion
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 70/100
medialab/xan#1201 · 2 comentários ·
Mantenedores costumam responder em até 1 dia
-
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 74/100
farion1231/cc-switch#8298 ·
Mantenedores costumam responder em até 1 dia