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
Maintainer antworten meist innerhalb von 1 Tag
Bewertung
- Schwierigkeit
- 4/5
- Geschätzter Aufwand
- 3-5 Tage
- Anfängerfreundlichkeit
- 35/100
Rechercherichtung
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.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Beschreibung
[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.
- Vorherrschende Sprache
- Rust
- Sterne
- 8
- Forks
- 1
- Ø Merge
- 16 Std. 35 Min.
- Gemergte PRs (30 T.)
- 574
Entwicklungsumgebung
- Kein Dockerfile und keine Docker-Compose-Datei
- Keine Pull-Request-Vorlage
- Beitragsleitfaden lesen
Erste Schritte
- Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
- Forken Sie das Repository und arbeiten Sie in einem Branch.
- Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.
Mehr aus SocketDev/socket-patch
-
agent:triaged bug bughunt pm:bundler priority:p1
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 70/100
SocketDev/socket-patch#1573 · 1 Kommentar ·
Maintainer antworten meist innerhalb von 1 Tag
-
agent:triaged bug bughunt pm:poetry priority:p1
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 80/100
SocketDev/socket-patch#1547 · 1 Kommentar ·
Maintainer antworten meist innerhalb von 1 Tag
-
agent:triaged bug bughunt pm:npm priority:p3 ux
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 75/100
SocketDev/socket-patch#1072 · 2 Kommentare ·
Maintainer antworten meist innerhalb von 1 Tag
-
agent:triaged bug bughunt pm:yarn-berry priority:p1
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 73/100
SocketDev/socket-patch#783 · 1 Kommentar ·
Maintainer antworten meist innerhalb von 1 Tag
-
Vendored cargo warns cargo_multi_version_old_cargo ("declares no rust-version") when the root package inherits rust-version from [workspace.package]Evtl. vergeben @mikolalysenko hat das vor 3 Tagen übernommen. Offenagent:triaged bug bughunt pm:cargo priority:p2
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 84/100
SocketDev/socket-patch#651 · 3 Kommentare ·
Maintainer antworten meist innerhalb von 1 Tag
Alle Issues in SocketDev/socket-patch
Ähnliche Issues
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 66/100
ActivityWatch/aw-notify-rs#47 · 1 Kommentar ·
-
`inverse()` of a controlled `CUGate` drops the phase parameter γEvtl. vergeben @rupasri118 hat das heute übernommen. Offenbug mod: circuit
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 66/100
Qiskit/qiskit#17223 · 1 Kommentar ·
Maintainer antworten meist innerhalb von 1 Tag
-
Schwierigkeit 1/5 Unter einer Stunde Anfängerfreundlichkeit 84/100
Maintainer antworten meist innerhalb von 2 Tagen
-
rustix::termios::Termios::OutputModes does not expost some const e.g. OLCUC for musl and macOSOffen
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 62/100
bytecodealliance/rustix#1706 · 1 Kommentar ·
Maintainer antworten meist innerhalb von 11 Tagen
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 62/100