[agent] Found by the scheduled Cargo bug-hunt routine (ledger #315).
Summary
scan --mode hosted skips a patched crate when its Cargo.toml declaration names the default registry explicitly: cfg-if = { version = "1.0.4", registry = "crates-io" }, or registry = "crates-io" in a [dependencies.cfg-if] table. It warns redirect_cargo_toml_dep_unrewritable … cannot be pinned (pinned to another registry ("crates-io")); dependency skipped (nothing rewritten), reports redirected: 0, and exits 0 with status: "success".
crates-io is Cargo's built-in name for crates.io, so this dependency is exactly the crates.io dependency hosted mode is built to redirect. Cargo resolves it identically to a declaration with no registry key: the baseline cargo build --locked succeeds, and the lock entry is source = "registry+https://github.com/rust-lang/crates.io-index". The refusal fires when it shouldn't.
Impact
Hosted mode never pins the patch for this dependency, so the project keeps building the unpatched crate. The only signal is a warning inside a success envelope. It fails closed: nothing is rewritten and nothing unpatched is attested. Vendored mode handles the same declaration correctly (vendor applies it, and cargo run --locked --offline links the patched marker), so the gap is hosted-only. Workaround: delete the redundant registry = "crates-io".
Repro
This uses the existing wiremock sparse-registry harness in crates/socket-patch-cli/tests/e2e_redirect_cargo_shapes.rs. Add a shape identical to cargo_hosted_legacy_config_is_restored_byte_for_byte, minus the config file, with this dependency line:
("Cargo.toml", consumer_manifest("cfg-if = { version = \"1.0.4\", registry = \"crates-io\" }\n")),
// or: consumer_manifest("") + "\n[dependencies.cfg-if]\nversion = \"1.0.4\"\nregistry = \"crates-io\"\n"
cargo test -p socket-patch-cli --test <file> then fails at the every patch redirected assertion:
"redirect":{"mode":"hosted","redirected":0,"rewrittenFiles":[],"skipped":[],
"warnings":[{"code":"redirect_cargo_toml_dep_unrewritable",
"detail":"cfg-if in Cargo.toml cannot be pinned (pinned to another registry (\"crates-io\")); dependency skipped (nothing rewritten)"}]}
The baseline steps before the scan pass: cargo generate-lockfile, and cargo build --locked with that manifest on cargo 1.93.1.
Expected vs actual
- Expected: docs/ecosystems.md (Cargo row) says hosted mode redirects direct crates.io dependencies through a per-patch sparse registry (
[registries.socket-patch-<uuid>] plus Cargo.lock source/checksum). A dependency whose registry is crates-io is a direct crates.io dependency, so the rewriter should replace the value with registry = "socket-patch-<uuid>", the same way it already replaces a stale socket-patch-* value.
- Actual: it's refused as "another registry", and nothing is redirected.
Matrix
| OS |
cargo |
inline { …, registry = "crates-io" } |
[dependencies.x] table |
control: no registry key |
| Linux |
1.93.1 |
fail (2/2 runs) |
fail (2/2 runs) |
pass |
| macOS / Windows |
— |
not probed: a pure text rewriter with no OS-specific branch |
|
|
In the same run, these shapes passed on Linux: optional = true with a [features] reference (both "cfg-if" and "dep:cfg-if"), default-features = false, a "1" caret requirement, a workspace where one member renames the dep, an idempotent re-scan, and cargo vendor after the redirect.
Suspect code
crates/socket-patch-core/src/patch/redirect/mod.rs:2547-2569 (table form) and :2665-2682 (inline form). A registry value other than the target or an is_socket_patch_registry_name value is refused. "crates-io" should be handled like a socket-patch name (replace the value) instead. The registry-index refusal next to it is a separate case, and it's fine.
Tested on main f6b7fb9 (CLI 4.0.0). I didn't bisect: the hosted cargo rewriter has had this branch since hosted mode shipped.
[agent] Found by the scheduled Cargo bug-hunt routine (ledger #315).
Summary
scan --mode hostedskips a patched crate when itsCargo.tomldeclaration names the default registry explicitly:cfg-if = { version = "1.0.4", registry = "crates-io" }, orregistry = "crates-io"in a[dependencies.cfg-if]table. It warnsredirect_cargo_toml_dep_unrewritable … cannot be pinned (pinned to another registry ("crates-io")); dependency skipped (nothing rewritten), reportsredirected: 0, and exits 0 withstatus: "success".crates-iois Cargo's built-in name for crates.io, so this dependency is exactly the crates.io dependency hosted mode is built to redirect. Cargo resolves it identically to a declaration with noregistrykey: the baselinecargo build --lockedsucceeds, and the lock entry issource = "registry+https://github.com/rust-lang/crates.io-index". The refusal fires when it shouldn't.Impact
Hosted mode never pins the patch for this dependency, so the project keeps building the unpatched crate. The only signal is a warning inside a
successenvelope. It fails closed: nothing is rewritten and nothing unpatched is attested. Vendored mode handles the same declaration correctly (vendorapplies it, andcargo run --locked --offlinelinks the patched marker), so the gap is hosted-only. Workaround: delete the redundantregistry = "crates-io".Repro
This uses the existing wiremock sparse-registry harness in
crates/socket-patch-cli/tests/e2e_redirect_cargo_shapes.rs. Add a shape identical tocargo_hosted_legacy_config_is_restored_byte_for_byte, minus the config file, with this dependency line:cargo test -p socket-patch-cli --test <file>then fails at theevery patch redirectedassertion:The baseline steps before the scan pass:
cargo generate-lockfile, andcargo build --lockedwith that manifest on cargo 1.93.1.Expected vs actual
[registries.socket-patch-<uuid>]plus Cargo.lock source/checksum). A dependency whoseregistryiscrates-iois a direct crates.io dependency, so the rewriter should replace the value withregistry = "socket-patch-<uuid>", the same way it already replaces a stalesocket-patch-*value.Matrix
{ …, registry = "crates-io" }[dependencies.x]tableregistrykeyIn the same run, these shapes passed on Linux:
optional = truewith a[features]reference (both"cfg-if"and"dep:cfg-if"),default-features = false, a"1"caret requirement, a workspace where one member renames the dep, an idempotent re-scan, andcargo vendorafter the redirect.Suspect code
crates/socket-patch-core/src/patch/redirect/mod.rs:2547-2569(table form) and:2665-2682(inline form). Aregistryvalue other than the target or anis_socket_patch_registry_namevalue is refused."crates-io"should be handled like a socket-patch name (replace the value) instead. Theregistry-indexrefusal next to it is a separate case, and it's fine.Tested on main
f6b7fb9(CLI 4.0.0). I didn't bisect: the hosted cargo rewriter has had this branch since hosted mode shipped.