Vendored NuGet on a core.autocrlf checkout: vendor --revert / remove / rollback revert packages.lock.json but leave nuget.config wired, so every restore fails NU1403 (vendor --revert exits 0)
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ó
- 4/5
- Thời gian dự kiến
- 3-5 ngày
- Mức phù hợp với người mới
- 45/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ệ
- git, rust
- Lĩnh vực
- build-system, cli
Hướng nghiên cứu
Start with the NuGet revert flow in crates/socket-patch-core/src/vendor/nuget_feed.rs, especially lines 728, 1180, 1206, and 1236. Run the reproduction in crates/socket-patch-cli/tests/e2e_nuget_dotnet_build.rs with a core.autocrlf=true checkout. Done means each revert path keeps the project restorable and reports an accurate result when nuget.config is CRLF-converted.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
[agent] Found by the scheduled NuGet / dotnet bug-hunt routine (ledger #320).
Summary
Vendored NuGet writes nuget.config with LF line endings and records the exact text it wrote. When the project is committed and then checked out with core.autocrlf=true (Git for Windows' default, and common on any OS), nuget.config and packages.lock.json come back with CRLF. On that checkout, every revert path ends up half-done:
- The lock record is reverted first (
revert_nuget_optswalks the wiring in reverse order). It's a JSON string swap, so CRLF doesn't affect it, andpackages.lock.jsongoes back to the upstreamcontentHash. - Then the config record is reverted. The whole-file fast path compares the live text with the recorded LF text, and the fallback excision looks for LF-terminated fragments (
" <add key=\"…\" value=\"…\" />\n"and" <packageSource key=\"…\">\n"). Neither matches CRLF, so the config is treated as drifted and left wired (vendor_lock_entry_drifted), and the artifact is kept.
The result is a project whose lock pins upstream bytes while nuget.config still maps Newtonsoft.Json exclusively to the vendored feed. Every later dotnet restore, locked or not, fails with NU1403: Package content hash validation failed.
vendor --revertexits 0 withstatus: success.remove <purl>exits 1 and says "every matching entry's vendored state drift-kept; nothing was removed". But it did rewritepackages.lock.json.rollbackexits 1 (partial_failure), and it also rewrites the lock.- The suggested remedy doesn't help. Re-running
scan --mode vendored, asvendor_revert_keptadvises, reportsalready_vendored/ "artifact and lockfile wiring already in sync", and the nextvendor --reverthalf-reverts again. vendor --checkon the same checkout reportsvendor_check_ok.
Impact
A Windows developer, or anyone using autocrlf=true, who clones a vendored NuGet project and tries to un-vendor it gets a project that no longer restores. vendor --revert reports success while doing it. The only way out is to fix the lock or config by hand, or to git checkout both files. There's nothing for the user to "undo", because the only drift is git's line-ending conversion of a file socket-patch itself committed.
Repro (Linux / macOS / Windows, any SDK)
I drove this with a scratch copy of crates/socket-patch-cli/tests/e2e_nuget_dotnet_build.rs: the same wiremock Backend stand-in, a real nuget.org fixture restore, and the real dotnet.
# app.csproj: net8.0, RestorePackagesWithLockFile=true, PackageReference Newtonsoft.Json 13.0.3
# nuget.config: nuget.org only (LF)
dotnet restore
socket-patch scan --mode vendored --vendor-source service --json --yes ... # rc 0; lock re-pinned, feed + mapping wired
git init && git add -A && git commit -m vendored
git clone -c core.autocrlf=true <repo> wc && cd wc # what Git for Windows does by default
file nuget.config # "... with CRLF line terminators"
dotnet restore --locked-mode # rc 0, PATCHED LICENSE.md installed (baseline ok)
socket-patch vendor --revert --json
# rc 0, "status": "success"
# events: skipped vendor_lock_entry_drifted "nuget.config no longer carries what vendor wrote for socket-patch-<uuid>; left alone"
# skipped vendor_artifact_kept, skipped vendor_revert_kept
git status --short # M packages.lock.json (lock reverted to the upstream contentHash)
grep -c socket-patch nuget.config # 2 (source + mapping still there)
rm -rf obj && dotnet restore --locked-mode # rc 1: error NU1403: Package content hash validation failed for Newtonsoft.Json.13.0.3
dotnet restore # rc 1: same NU1403
remove pkg:nuget/[email protected] (rc 1, vendor_revert_kept "nothing was removed") and rollback (rc 1) leave exactly the same state: lock modified, config wired, NU1403. Running scan --mode vendored first and then vendor --revert behaves the same way.
Control: on the same commit cloned without autocrlf, vendor --revert restores both files byte-for-byte and the locked restore installs the pristine package.
Expected vs actual
- Expected: CLI_CONTRACT.md says
vendor --revert"restores the originals". Drift-keep is for fragments "that no longer match — a user re-resolved", and it should keep the project restorable. The contract already treats a checkout's line-ending conversion as something revert must survive for cargo ("remove/ rollback match the recorded fragments across a later CRLF↔LF checkout conversion"). The minimum is that a revert which keeps the config wired must not revert the lock pin on its own, and must not reportsuccess/ "nothing was removed". - Actual: a git line-ending conversion counts as drift. The lock is reverted anyway, the config isn't, and the project can't restore.
OS × version (probe run, all with git clone -c core.autocrlf=true)
| OS | SDK | vendor --revert | remove | rollback | rescan → revert |
|---|---|---|---|---|---|
| Linux (sandbox) | 8.0.131 | repro (rc 0) | repro (rc 1) | repro (rc 1) | repro |
| ubuntu-latest | 8.0.x, 10.0.x | repro | repro | repro | repro |
| macos-latest | 8.0.x | repro | repro | repro | repro |
| macos-latest | 10.0.x | job ran; I only inspected the named-lock cells in its log | |||
| windows-latest (Git for Windows, system autocrlf=true) | 8.0.x, 10.0.x | repro | repro | repro | repro |
| any | any, no autocrlf (control) | pass | pass | pass | pass |
Reproduced 3× in the sandbox on main 61cfb9b, and on every probe cell: https://github.com/SocketDev/socket-patch/actions/runs/36970426074
Not bisected. The LF-anchored fragments in the NuGet revert look as old as the vendored NuGet backend.
Suspect code
crates/socket-patch-core/src/vendor/nuget_feed.rs:1180: the whole-file fast pathw.new == liveis exact-byte.crates/socket-patch-core/src/vendor/nuget_feed.rs:1206and:1236: the excision fragments are hard-coded with\n(source_add,excise_source_mapping), so a CRLF file always falls toOk(false)at:1210.crates/socket-patch-core/src/vendor/nuget_feed.rs:728: the reverse-order loop reverts the lock record before the config record and doesn't undo it when the config is drift-kept. That turns a "left alone" into a broken half-revert.- The vendored nupkg itself is untouched by autocrlf, because git detects it as binary. Vendor writes no
.gitattributesfornuget.config/packages.lock.json; compare #429, the Gradle counterpart of this autocrlf class.
- 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
- Không có Dockerfile hay tệp Docker Compose
- Không có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- 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.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của SocketDev/socket-patch
-
arch-audit refactor
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
SocketDev/socket-patch#1011 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
agent:triaged arch-audit bug priority:p3
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 74/100
SocketDev/socket-patch#982 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Hosted yarn classic pins give no berry-migration warning, so a yarn 2+ install silently drops them (vendored warns about the same trap)Có thể đã có người làm @mikolalysenko đã nhận 1 ngày trước. Đang mởagent:claimed agent:triaged bug bughunt pm:yarn-classic priority:p1
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 85/100
SocketDev/socket-patch#907 · 2 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
agent:triaged bug bughunt pm:bundler priority:p1
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 85/100
SocketDev/socket-patch#896 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
agent:triaged bug bughunt pm:yarn-berry priority:p1
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 73/100
SocketDev/socket-patch#783 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
Tất cả issue của SocketDev/socket-patch
Issue tương tự
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 74/100
rubys/roundhouse#571 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 74/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 70/100
-
documentation
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 90/100
fastrevmd-lab/rustmistmcp#161 ·
-
bug user-priority/P2
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 92/100
Maintainer thường phản hồi trong vòng 1 ngày