[agent] Found by the scheduled Yarn classic (1.x) bug-hunt routine (ledger #304).
Summary
The #364 fix (#839) refuses a hosted yarn classic rewrite when the project sets yarn-offline-mirror, with redirect_yarn_classic_offline_mirror. The two readers behind that gate, yarnrc_value_of_offline_mirror and npmrc_value_of_offline_mirror, don't skip a leading UTF-8 BOM. On a file that starts with a BOM, the first line's key reads as \u{feff}yarn-offline-mirror, which never equals yarn-offline-mirror, so the mirror goes unseen. str::trim doesn't remove U+FEFF.
Yarn 1.10.1 and 1.22.22 do honour a BOM-prefixed .yarnrc and .npmrc: the initial install fills ./mirror either way. So the scan pins the hosted URL, reports success with no warning, and VEX attests not_affected. Every frozen install then fails the integrity check, because yarn takes the upstream tarball from the mirror by basename. That's exactly what #364 was about.
The same gate runs before a vendored→hosted takeover, so a takeover reverts a working vendored entry and replaces it with a hosted pin that can't install.
This is a separate cause from #1013, which is about where the mirror is configured (outside the project). Here the setting is in the project's own .yarnrc, which #839 covers when the file has no BOM. A BOM is common on Windows, for example from Notepad or Windows PowerShell 5 Set-Content -Encoding utf8.
Impact
On yarn ≥ 1.10, a project whose mirror config has a BOM gets a lock that no yarn install (frozen, plain or --offline) can install. The scan reports redirected: 1, and VEX attests a patch that is never installed. A vendored project taken over to hosted goes from patched to uninstallable.
Repro (Linux, main 05ecc6e, local mock patch API on :8787)
mkdir p && cd p
printf '\xef\xbb\xbfyarn-offline-mirror "./mirror"\n' > .yarnrc # same with \r\n, or .npmrc: yarn-offline-mirror=./mirror
echo '{"name":"p","version":"1.0.0","private":true,"dependencies":{"left-pad":"1.3.0"}}' > package.json
yarn install # mirror/left-pad-1.3.0.tgz is written, so yarn read the BOM file
socket-patch scan --mode hosted --vex v.json --json --yes --api-url http://127.0.0.1:8787 --org o --api-token x
# → exit 0, "redirected": 1, no redirect_yarn_classic_offline_mirror; v.json: not_affected
mkdir ../f && cp -r package.json yarn.lock .yarnrc mirror ../f && cd ../f
yarn install --frozen-lockfile # → exit 1: Integrity check failed for "left-pad"
yarn install --frozen-lockfile --offline # → exit 1: Can't make a request in offline mode
Takeover variant: run scan --mode vendored first (its fresh frozen install is patched), then scan --mode hosted. With the BOM it says redirect_takeover_reverted_vendored, redirected: 1, and the fresh frozen install fails as above. Without the BOM it refuses with redirect_yarn_classic_offline_mirror and stays vendored and patched.
Expected vs actual
- Expected: CLI_CONTRACT and docs/ecosystems.md describe
redirect_yarn_classic_offline_mirror as the refusal for a project that sets yarn-offline-mirror. The readers should parse the file as yarn does: skip a leading BOM, as the crawler's .yarnrc reader already does (npm_crawler.rs, BOM + CRLF test near line 5851). Then the scan refuses and leaves yarn.lock untouched.
- Actual: the scan exits 0 with
redirected: 1, no warning and a not_affected attestation, and every install then fails.
Matrix (Linux, Node 22; each cell run twice)
| yarn |
rc file |
scan |
fresh frozen install |
--offline install |
VEX |
| 1.10.1 |
.yarnrc BOM (LF and CRLF) |
pins, exit 0 |
exit 1, integrity |
exit 1 |
not_affected |
| 1.22.22 |
.yarnrc BOM (LF and CRLF) |
pins, exit 0 |
exit 1, integrity |
exit 1 |
not_affected |
| 1.22.22 |
.npmrc BOM |
pins, exit 0 |
exit 1, integrity |
exit 1 |
not_affected |
| 1.22.22 |
.yarnrc BOM, vendored→hosted takeover |
reverts + pins |
exit 1, integrity |
n/a |
n/a |
| 1.7.0 |
.yarnrc BOM |
pins |
exit 0, patched (no integrity lines in 1.7 locks) |
exit 0 |
not_affected |
| 1.10.1 / 1.22.22 |
.yarnrc / .npmrc without a BOM (control) |
refused redirect_yarn_classic_offline_mirror |
exit 0, unpatched (expected) |
exit 0 |
none |
macOS and Windows weren't run. The parser is OS-independent, and Windows is where BOM-prefixed rc files are most common.
Suspect code
[agent] Found by the scheduled Yarn classic (1.x) bug-hunt routine (ledger #304).
Summary
The #364 fix (#839) refuses a hosted yarn classic rewrite when the project sets
yarn-offline-mirror, withredirect_yarn_classic_offline_mirror. The two readers behind that gate,yarnrc_value_of_offline_mirrorandnpmrc_value_of_offline_mirror, don't skip a leading UTF-8 BOM. On a file that starts with a BOM, the first line's key reads as\u{feff}yarn-offline-mirror, which never equalsyarn-offline-mirror, so the mirror goes unseen.str::trimdoesn't remove U+FEFF.Yarn 1.10.1 and 1.22.22 do honour a BOM-prefixed
.yarnrcand.npmrc: the initial install fills./mirroreither way. So the scan pins the hosted URL, reports success with no warning, and VEX attestsnot_affected. Every frozen install then fails the integrity check, because yarn takes the upstream tarball from the mirror by basename. That's exactly what #364 was about.The same gate runs before a vendored→hosted takeover, so a takeover reverts a working vendored entry and replaces it with a hosted pin that can't install.
This is a separate cause from #1013, which is about where the mirror is configured (outside the project). Here the setting is in the project's own
.yarnrc, which #839 covers when the file has no BOM. A BOM is common on Windows, for example from Notepad or Windows PowerShell 5Set-Content -Encoding utf8.Impact
On yarn ≥ 1.10, a project whose mirror config has a BOM gets a lock that no
yarn install(frozen, plain or--offline) can install. The scan reportsredirected: 1, and VEX attests a patch that is never installed. A vendored project taken over to hosted goes from patched to uninstallable.Repro (Linux, main
05ecc6e, local mock patch API on :8787)Takeover variant: run
scan --mode vendoredfirst (its fresh frozen install is patched), thenscan --mode hosted. With the BOM it saysredirect_takeover_reverted_vendored,redirected: 1, and the fresh frozen install fails as above. Without the BOM it refuses withredirect_yarn_classic_offline_mirrorand stays vendored and patched.Expected vs actual
redirect_yarn_classic_offline_mirroras the refusal for a project that setsyarn-offline-mirror. The readers should parse the file as yarn does: skip a leading BOM, as the crawler's.yarnrcreader already does (npm_crawler.rs, BOM + CRLF test near line 5851). Then the scan refuses and leavesyarn.lockuntouched.redirected: 1, no warning and anot_affectedattestation, and every install then fails.Matrix (Linux, Node 22; each cell run twice)
--offlineinstall.yarnrcBOM (LF and CRLF).yarnrcBOM (LF and CRLF).npmrcBOM.yarnrcBOM, vendored→hosted takeover.yarnrcBOMintegritylines in 1.7 locks).yarnrc/.npmrcwithout a BOM (control)redirect_yarn_classic_offline_mirrormacOS and Windows weren't run. The parser is OS-independent, and Windows is where BOM-prefixed rc files are most common.
Suspect code
crates/socket-patch-core/src/patch/redirect/mod.rs:3364yarnrc_value_of_offline_mirror:line.trim()leaves U+FEFF on the first key.crates/socket-patch-core/src/patch/redirect/mod.rs:3395npmrc_value_of_offline_mirror: the same.