GeezerVison is showing github.com — Fix hosted cargo pins for multi-line inline tables (#757) by mikolalysenko · Pull Request #1735 · SocketDev/socket-patch
Conversation
LLM Description written by Claude Code:claude-opus-5-5
Refs #757
Root cause
Hosted cargo plans Cargo.toml pins with a line scanner that treated every inline table as one line (plan_cargo_toml in crates/socket-patch-core/src/patch/redirect/mod.rs). It refused a valid TOML 1.0 declaration whose array value wraps, which is rustfmt's style for a long feature list:
serde = { version = "1.0.0", features = [
"derive",
] }
scan --mode hosted warned redirect_cargo_toml_dep_unrewritable and left the crate unpatched, although the same project vendors fine. The pin readers (CargoRegistryPins and its test oracle cargo_socket_registry_pin) and upstream restore's unpin_line made the same one-line assumption.
Changes
cargo_inline_table: one brace-, bracket-, string- and comment-aware reader for an inline table. It returns the closing line and the text between the braces, borrowed when the table closes on its own line. It allows a line break only inside an array or a multi-line string, as TOML 1.0 does, so {⏎ version = … } is still refused. Comment text is left out, so a key named only in a comment is not read as one.
- Planner: every inline table goes through that reader. A wrapped table is classified on its whole text with the existing rules and pinned on its opening line (
registry = "<reg>", straight after {). An earlier Socket pin in that spelling is superseded in place. An explicit registry = "crates-io" (Hosted cargo redirect refuses a crates.io dependency declared with an explicit registry = "crates-io", treating crates.io as "another registry" #386) anywhere in the wrapped table is dropped and the pin written in that spelling, so remove leaves the declaration without the redundant key, as it does for one-line tables. Any other registry already named in a wrapped table is still refused, because restore could not unpin it. Lines inside a wrapped table are skipped, so they are never read as entries or headers.
CargoRegistryPins and the oracle read pins out of the same span.
- Upstream restore drops exactly the inserted text from the opening line, so
rollback / remove leave the manifest byte-identical.
Not in this PR (why Refs, not Fixes)
#757's acceptance table also lists serde.version = "1.0.0" (dotted keys) and serde = '1.0.0' (literal string). Both stay refused. Supporting them, and deleting the regex scanner, is the larger toml_edit planner rewrite the issue proposes. I'm leaving the issue open for that.
Tests (red → green)
Before the fix, run against origin/main's core:
patch::redirect::tests::cargo_multiline_inline_table_is_pinned_on_its_opening_line (LF and CRLF; comments in the array; a rename): red, refused.
patch::redirect::tests::cargo_multiline_inline_table_is_classified_by_its_whole_text (path key after the array; renamed-away table; keys and braces only in comments; "a}" and """q"""" strings; already pinned): red.
patch::redirect::tests::cargo_socket_registry_pin_reads_back_every_written_shape with two new multi-line shapes: red.
patch::redirect::tests::cargo_supersede_replaces_previous_multiline_pin: re-pin to a newer patch.
upstream::cargo::tests::multiline_inline_table_opening_line_loses_only_the_pin and restore_unpins_a_multiline_inline_table_byte_exact (LF, CRLF, BOM, CRLF+BOM): red, restore refused.
- Real cargo,
e2e_redirect_cargo_shapes::cargo_hosted_multiline_inline_table_is_pinned (LF and CRLF; cargo 1.93.1): red on main (skipped: no lockfile entry pinning it could be rewritten). Green with the fix: scan, fresh-checkout cargo fetch --locked + offline cargo build --locked links the patched symbol, vex attests, remove is byte-identical.
- I also checked by hand that
cargo 1.97.0 metadata reads a pinned wrapped declaration (with comments and default-features = false) as serde from the Socket registry, with its features kept.
mode_migration_cargo::takeover_over_unrewritable_spelling_keeps_vendored listed the wrapped table as a spelling hosted mode refuses. Now that it's pinned, I removed that row. The dotted and literal rows stay.
Per issue:
Local gates
cargo fmt --all -- --check: clean.
cargo clippy --workspace --all-features -- -D warnings: clean.
cargo test -p socket-patch-core --all-features --lib: 6795 passed, 4 failed. All 4 are chmod/unremovable-file tests that can't fail as root, which this container runs as: copy_tree::relax_loop_must_not_traverse_symlinked_root, vlt_heal::an_unremovable_hidden_lock_keeps_every_store_entry, pypi_poetry::wire_write_failure_… and pypi_requirements::wire_failure_…. Fix berry unwind under a user yarn patch (#962) #1733 lists the same tests. None of them touch this diff.
- CLI suites, with
SOCKET_PATCH_CARGO_E2E_REQUIRED=1: e2e_redirect_cargo_shapes 34/34, e2e_redirect_cargo_build 23/23, e2e_vendor_cargo_build 40/40, mode_migration_cargo 30/30, in_process_cargo_apply 23/23, e2e_cargo 25/25.
- I didn't run the full
cargo test --workspace: building every CLI test binary ran this container out of disk. CI runs the rest.
- No wrapper changes (
npm/, pypi/, gem/ only dispatch the binary).
/code-review high
Fixed in 20f1ef5:
- comment text leaking into classification;
- the
find('}') dispatch, which a } in a comment or string broke, in planner, readers and restore;
- no supersede for an earlier multi-line pin;
- multi-line strings that end in extra quotes;
- the dispatch block repeated three times, now one helper;
- a new allocation per single-line table, now
Cow.
Nothing was left unfixed.
CI
All checks green on 319351f (37 success, the rest skipped). Cursor Bugbot found no new issues on 319351f.
Bugbot
- 20f1ef5: wrapped tables naming
crates-io were refused. Fixed in bde22cd, with unit tests for three placements and a crates-io-wrapped real-cargo e2e row. Thread resolved.
- bde22cd: the wrapped crates-io matcher missed
'crates-io' and "registry" spellings. Fixed in 319351f, with tests. Thread resolved.
https://claude.ai/code/session_011f9aeSkjzuMR7wJ9h5JWZd
Generated by Claude Code
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Assisted-by: Claude Code:claude-opus-5-5
Hosted cargo scan refused a Cargo.toml dependency written as an inline
table whose array wraps onto later lines, the usual rustfmt style for
a long feature list:
serde = { version = "1.0.0", features = [
"derive",
] }
It warned redirect_cargo_toml_dep_unrewritable and left the crate
unpatched. The planner, the pin readers and upstream restore all
assumed an inline table closes on its own line.
A shared reader now follows such a table to its closing brace. It only
lets a line break happen inside an array or a multi-line string, as
TOML 1.0 does, so a break straight after "{" is still refused. The
planner classifies the whole table text and pins it on the opening
line, right after "{". The pin readers read that pin back, and restore
removes exactly the inserted text, so rollback leaves the manifest
byte-identical for LF, CRLF and BOM files.
Refs #757
Assisted-by: Claude Code:claude-opus-5-5
Follow-ups from review of the multi-line inline table support:
- Keys or braces that appear only in a comment inside a wrapped
features array no longer get the dependency refused as a path,
workspace or other-registry entry, or pinned inside the comment.
- Every inline table, one-line or wrapped, is now read by the same
brace- and string-aware scanner. A "}" inside a string or comment no
longer ends it, and a multi-line string may end in extra quotes.
- A rescan that picks a newer patch moves an earlier pin on a wrapped
table to the new registry, the same as it does for every other
spelling.
- Restore uses the same scanner to tell a wrapped table's opening line
from a one-line table.
- A real-cargo e2e shape covers the wrapped spelling for LF and CRLF:
scan, offline locked build, vex, and a byte-exact remove. The
migration test no longer lists it as a spelling hosted mode refuses.
Refs #757
Assisted-by: Claude Code:claude-opus-5-5
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
cursor
Bot
left a comment
•
edited
Loading
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Stale Bugbot comment from a previous run.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
A wrapped inline table with an explicit registry = "crates-io" was
still refused, while #386 pins the one-line form. Hosted scan now
drops that redundant key, with one adjacent comma, and pins the table
on its opening line in the spelling restore unpins. remove then leaves
the declaration without the key, which cargo resolves the same way, as
it does for the one-line form. Unit tests cover the key after "{", in
the middle of the opening line and on the closing line. A real-cargo
e2e row covers the closing-line spelling.
Refs #757
Assisted-by: Claude Code:claude-opus-5-5
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
cursor
Bot
left a comment
•
edited
Loading
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Stale Bugbot comment from a previous run.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
The crates-io repin for a wrapped inline table found only the bare key
with a double-quoted value. registry = 'crates-io' and
"registry" = "crates-io" mean the same thing, and the one-line form
already accepts them, but in a wrapped table they still got the
dependency refused. The matcher now takes the same key and value
spellings as the one-line rewrite.
Refs #757
Assisted-by: Claude Code:claude-opus-5-5
cursor[bot] reacted with thumbs up emoji
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 319351f. Configure here.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
Burn-down agent: labeled Ready for review at head 319351f.
Generated by Claude Code
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
Burn-down agent: labeled Ready for review at head 319351f.
- CI: 56/56 check runs on
319351f passed or skipped (37 success, 19 skipped); mergeable with main, no conflicts. No main-wide failures.
- Cursor Bugbot: reviewed
319351f, no new issues. Its two earlier findings (wrapped tables naming crates-io; 'crates-io'/"registry" spellings) were fixed in bde22cd and 319351f; both threads resolved.
CHANGELOG.md untouched.
- Reviewer note: this is
Refs #757, not Fixes. Dotted-key and literal-string spellings stay refused and are left for the toml_edit planner rewrite.
Generated by Claude Code
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Final review brief (head 319351f)
What it does. Hosted cargo mode refused a dependency written as an inline table whose features array wraps lines (rustfmt's style), so scan --mode hosted left the crate unpatched (#757). This adds one string-, comment- and bracket-aware reader for inline tables. The planner, the pin readers and upstream restore all use it. A wrapped table is pinned right after its opening {, and restore drops exactly that text. Dotted-key and literal-string spellings are still refused (left for the toml_edit rewrite, hence Refs).
Risk: low. The change is limited to cargo manifest spellings that used to be refused. One-line tables take the same path as before, apart from the new close detection, which now ignores } inside strings and comments. Restore is byte-exact for LF, CRLF and BOM, and that is tested.
Look here
Verified
- I read the full diff. I traced comma handling for the crates-io key at the start, middle and end of the table, CRLF
\r carry-through, lines inside a wrapped table being skipped (they used to be scanned as entries), and supersede of an earlier pin.
- The tests are red→green per the description. The real-cargo e2e covers LF and CRLF.
- Locally on
319351f: cargo clippy --locked -p socket-patch-core --all-features -- -D warnings is clean. cargo test -p socket-patch-core --lib cargo passed 472/472. cargo fmt --check is clean.
- CI: 37 success, 19 skipped, 0 failed.
ci-ok and clippy are green. Bugbot found no issues on this head. All review threads are resolved. CHANGELOG.md is untouched.
Changes I made: none.
Open questions (non-blocking): in a wrapped table that has registry = "crates-io", a # inside a string on the same line as the key (say features = ["a#b"], registry = "crates-io" }) makes the crates-io drop give up. The crate is then refused with a warning, the same outcome as before this PR. This is conservative, and I didn't change it.
Auto-merge is armed, so approving sends this straight to the merge queue.
Generated by Claude Code
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
This was referenced Oct 27, 2026
Uh oh!
There was an error while loading. Please reload this page.
This was referenced Oct 27, 2026
Uh oh!
There was an error while loading. Please reload this page.
Assignees
No one assigned
Labels
Ready for review
Agent-verified: mergeable, CI green, Bugbot clean — awaiting human review
Milestone
No milestone
Development
Successfully merging this pull request may close these issues.
Uh oh!
There was an error while loading. Please reload this page.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
|