Hacktoberfest 2026:維護者為十月標記出來的 issue,仍然開放、適合新手。 瀏覽 Hacktoberfest issue

Composer vendored → hosted takeover rewrites the vendored lock entry in place, keeping the patch-uuid dist.reference and transport-options: Composer 1 install crashes and rollback refuses

未關閉
#536 2 則留言 0 個 reaction 已指派 0 人 在 GitHub 檢視

維護者通常 1 天內回覆

還沒有人認領這個 Issue。

評估

難度
4/5
預估耗時
3-5 天
新手友好度
68/100
Issue 類型
缺陷
描述清晰度
描述清楚
活躍度
活躍
技術堆疊
php, rust
領域
cli, tooling

研究方向

Start in crates/socket-patch-cli/src/commands/scan/hosted.rs:1512 to trace Composer takeover dispatch, then inspect crates/socket-patch-core/src/formats/composer/hosted.rs:154 and the takeover reconciliation guidance in CLI_CONTRACT.md. Reproduce the vendored-to-hosted flow from the issue and check docs/testing/composer-compatibility.md. Done means the result matches a direct hosted scan, installs on supported Composer versions, and rollback can restore it.

由索引模型根據 Issue 內容生成。

描述

agent:triaged bug bughunt pm:composer priority:p2

[agent] Found by the scheduled Composer bug-hunt routine (ledger #321).

Summary

scan --mode hosted over a project whose Composer package is currently vendored doesn't revert the vendored wiring first, unlike cargo, npm and golang (and PyPI in open PR #503). The hosted rewriter edits the vendored lock entry in place. It changes dist.type from path to zip, points dist.url at the hosted archive and sets shasum. It keeps two fields that socket-patch's vendored mode wrote:

  • "dist.reference": "<patch uuid>" (vendored mode replaces the upstream commit with the patch uuid)
  • "transport-options": {"symlink": false}

The run only warns redirect_supersedes_vendored and tells the user to run socket-patch remove <purl>. Following that advice doesn't touch the lock ("composer.lock entry … no longer points into .socket/vendor/composer/; left alone").

Impact

  1. Composer 1.10 can't install the project at all. It passes transport-options into stream_context_create(), which fails with Uncaught ValueError: Options should have the form ["wrappername"]["optionname"] = $value (StreamContextFactory.php:153, exit 255). This is the same Composer 1 failure mode #399 reported for path repositories, but here socket-patch wrote the offending key itself.
  2. rollback refuses, so the hosted state can't be undone except through git: Cannot restore pkg:composer/psr/[email protected] to its upstream registry entry: … the lock pins dist.reference "9f6b2c4e-…" but packagist now serves "f16e1d58…"; restore it from version control instead.
  3. The committed .socket/vendor/composer/<uuid>/ artifact and its ledger entry are orphaned (warned about, but not reconciled).

The other direction works correctly. Hosted → vendored restores the upstream packagist entry first (vendor_takeover_reverted_redirect). Running vendor --revert and then scan --mode hosted produces a lock byte-identical to a direct hosted scan, and that lock installs patched on Composer 1.10.28.

Repro (Linux, main 61cfb9b)

The fixture is a real packagist-origin lock: composer.json {"require":{"psr/log":"3.0.2"}}, created with composer update --no-install. A local mock of the patch API grants uuid 9f6b2c4e-1d3a-4f6b-8c2d-7e5a9b1c3d5f for pkg:composer/psr/[email protected] (patches/package with sha1 and sha512 integrity, plus a single-top-dir zip of the patched package). secure-http: false is set in $COMPOSER_HOME/config.json for the loopback mock.

A="--api-url http://127.0.0.1:8766 --org test-org --api-token fake --patch-server-url http://127.0.0.1:8766"
socket-patch scan --mode vendored --yes $A        # exit 0; lock -> dist: path, reference: <uuid>, transport-options {symlink:false}
git add -A && git commit -qm vendored
socket-patch scan --mode hosted --json --yes $A   # exit 0, redirected: 1, warnings: [redirect_supersedes_vendored]
jq '.packages[0] | {dist, source, "transport-options"}' composer.lock
# {"dist":{"type":"zip","url":"http://127.0.0.1:8766/patch/composer/psr/log/3.0.2/<tok>/9f6b2c4e-…/log-3.0.2.zip",
#          "reference":"9f6b2c4e-1d3a-4f6b-8c2d-7e5a9b1c3d5f","shasum":"40b75d18…"},
#  "source":null,"transport-options":{"symlink":false}}
rm -rf vendor && php composer-1.10.28.phar install   # PHP Fatal error: Uncaught ValueError … StreamContextFactory.php:153 (exit 255)
socket-patch rollback --yes $A                       # exit 1: lock pins dist.reference "9f6b2c4e-…" but packagist now serves "f16e1d58…"
socket-patch remove pkg:composer/psr/[email protected] --yes $A   # reverts the ledger entry/artifact; composer.lock left unchanged

Control on the same fixture: vendor --revert → scan --mode hosted gives reference: f16e1d58… with no transport-options, and Composer 1.10.28 installs the patched bytes.

Expected vs actual

  • Expected: CLI_CONTRACT.md, "Takeover reconciliation", says "Hosted → vendored and vendored → hosted (redirect_takeover_reverted_vendored) both work in place on the locks the target mode accepts". A vendored Composer purl should be reverted to its recorded original (upstream) entry before the hosted rewrite, as cargo, npm and golang are. The result should match a direct hosted scan: an installable lock on every supported Composer version (docs/testing/composer-compatibility.md: 1.10 → 2.10) that rollback can restore.
  • Actual: the vendored entry is rewritten in place. The patch-uuid reference and transport-options survive, Composer 1 can't install, and rollback refuses.

Matrix (reproduced twice from scratch, plus the original run)

OS Composer (PHP) Install after vendored → hosted rollback
Linux 1.10.28 (8.3) fails, ValueError, exit 255 refuses (reference mismatch)
Linux 2.2.30 (8.3) installs patched refuses
Linux 2.8.12 (8.3) installs patched refuses
Linux 2.10.3 (8.3) installs patched refuses

macOS and Windows weren't probed. The trigger is pure lock text, and #399's probe (https://github.com/SocketDev/socket-patch/actions/runs/36903408294) already shows that Composer 1.10.28 crashes on any non-stream transport-options key on ubuntu, macOS and Windows, on PHP 7.2–8.4.

Not bisected: with these flags, v4.0.0's vendored scan exits 1, so it gives no baseline.

Suspect code

  • crates/socket-patch-cli/src/commands/scan/hosted.rs:1512: takeover_capable only admits pkg:cargo/, pkg:npm/ and pkg:golang/ (PR #503 adds pkg:pypi/), so a vendored pkg:composer/ purl skips dispatch_revert_one and goes straight to the rewriter.
  • crates/socket-patch-core/src/formats/composer/hosted.rs:154 (rewrite_composer_lock) keeps the entry's transport-options and dist.reference. The transport-options part is the same root cause as #399; this issue is about the missing takeover revert.
主要語言
Rust
星號
8
分支
0
平均合併
1 天 1 小時
30 天內合併 PR
211

環境準備

  • 沒有 Dockerfile 或 Docker Compose 檔案
  • 沒有 Pull Request 範本
  • 閱讀貢獻指南

從這裡開始

  1. 先讀完整個 Issue,再讀專案的貢獻指南。
  2. 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
  3. Fork 儲存庫,在一個分支上完成修改。
  4. 送出 Pull Request,並在描述裡引用這個 Issue 編號。

SocketDev/socket-patch 的其他 Issue

查看 SocketDev/socket-patch 的全部 Issue

相似的 Issue

更多 Rust Issue

把新 issue 寄到你的電子郵件信箱

精選適合新手參與的 GitHub issue 摘要。