GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | ||||||||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | ||||||||||||||
GeezerVison is showing github.com — Fix VEX attesting beside an unpatched same-lock copy (#935, #938, #939) by mikolalysenko · Pull Request #940 · SocketDev/socket-patch Conversation
|
| Issue | Test |
|---|---|
| #935 | vex::discover::npm::tests::issue_935_same_lock_file_copy_contests_the_pnpm_ref: v9 dir, v9 tgz, legacy dir, plus controls (wiring alone; dir of another version) |
| #938 | vex::discover::yarn::tests::issue_938_classic_registry_block_of_the_same_version_contests_the_ref: plus control (registry block of another version) |
| #939 | vex::discover::yarn::tests::issue_939_berry_other_name_copy_contests_the_ref: file: tgz, file: dir, registry url, plus controls (wiring alone; file: copies holding another package) |
The existing classic_git_pattern_copies_are_never_attested also went red with the shared pass disabled, which confirms git copies now go through it.
Local runs:
cargo test -p socket-patch-core --all-features --lib: 5248 passed. 4 permission-based tests fail only because this sandbox runs as root (copy_tree symlinked root, vlt_heal unremovable lock, poetry / requirements write failure). They pass in CI on main's head. The 5th failure was the digest guard, fixed by the Route Gradle digests through utils::digest #878 port.cargo test -p socket-patch-cli --all-features --lib --test e2e_vex_lockfile --test e2e_vex_redirect --test e2e_vex_vendor --test e2e_vex --test covgap_commands_vex: all green (847 + 12 + 19 + 311 + 31 + 28).cargo clippy --workspace --all-features -- -D warnings: clean.redirect-npm.json): regenerated. The only change is an additive unpatched_copies section on yarn classic fixtures. No ref or diagnostic changed.cargo fmt: touched files are formatted. main itself isn't cargo fmt --check clean (about 120 files), and CI doesn't run fmt.yarn-classic/hosted / rescan by 16–18% because of a quadratic per-insert dedup. 980b7b6 removes it. A local socket-patch-bench compare --filter yarn-classic against main then shows +1.4% [-10.4, +8.1] and -3.0% [-8.1, +3.3], both ≈.The npm / PyPI / gem wrappers don't need changes: this is Rust-only discovery logic.
🤖 Generated with Claude Code
https://claude.ai/code/session_01RpNijzXr9S3AZY6xHUDwVH
Note
Medium Risk
Changes VEX discovery and attestation eligibility for npm-family locks when duplicate same-version install paths exist; behavior is fail-closed (drops refs, emits diagnostics) but affects security-relevant VEX output.
Overview
Stops false VEX not_affected claims when a lockfile both wires a package to a Socket patch and still installs an unpatched copy of the same name@version in that same lock—something cross-lock contest_across_locks never saw because it ignores evidence from the ref’s own file.
Discovery now has a shared unpatched_copy / contest_within_locks path: extractors record competing lock entries (with key + how they install), those copies also count as resolved_elsewhere, and matching refs are dropped with patched_ref_unattributable diagnostics that name the copy. The pass runs after all extractors and before cross-lock contesting.
pnpm (#935): file: directory and tarball entries (v9 and legacy keys); package identity from lock fields or the copy’s package.json / tarball.
Yarn classic (#938): non-Socket registry tarball blocks beside a Socket block (replacing a yarn-only post-filter); git and file: directory copies go through the same API.
Yarn berry (#939): file: / URL locators keyed under another dependency name; real package name from tarball, directory manifest, or registry URL path.
Golden discovery output gains an unpatched_copies section; regression tests cover the three issues plus controls (wrong version, different package, wiring alone).
Reviewed by Cursor Bugbot for commit acbac79. Configure here.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
A lockfile-only `vex` attested a package as not_affected while the same lock also installed an unpatched copy of that exact name@version: - pnpm: a `file:` directory or tarball copy (#935) - yarn classic: a registry block left beside the Socket block, e.g. after `yarn add -W left-pad --exact` (#938) - yarn berry: a `file:` / url copy locked under another dependency name, which the `resolutions` pin never reaches (#939) The cross-lock contest only weighs OTHER locks, and each extractor wrote its own same-lock rule (npm and yarn classic git only). Discovery now has one shared same-lock rule: extractors record an unpatched copy and every ref of the same name@version in that lock is dropped with a patched_ref_unattributable diagnostic naming the copy. Yarn classic's git-copy filter moves onto it. The berry and pnpm extractors read the copy's real package from its package.json (directory or tarball) or from the registry tarball url. Assisted-by: Claude Code:claude-opus-5-5
main has failed socket-patch-core's lib tests since Gradle support (#646) and the digest helpers (#865) both landed. The guard test production_digests_go_through_the_helpers flags three files #646 added that still hash inline: crawlers/gradle_cache.rs, patch/jvm_jar.rs and patch/sidecars/maven.rs. That breaks test, test-release and coverage on every open PR. Each inline sha1/sha256 call now goes through sha1_hex_of or sha256_hex_of, which compute the same lowercase hex. Behaviour is unchanged. Assisted-by: Claude Code:claude-opus-5-5 (cherry picked from commit 659ac2c)
Every non-Socket yarn classic block is now recorded as a possible unpatched copy, and each record scanned the whole list for a duplicate first. On a 3000-package lock that made hosted scans and rescans about 17% slower in the scan benchmark. The list is already sorted and deduplicated once when discovery finishes, so the per-record scan goes. Assisted-by: Claude Code:claude-opus-5-5
|
BugBot review Generated by Claude Code |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
[agent]
The run is still in progress, so GitHub won't re-run the failed job yet (403 "already running"). I'll re-run it once when the run finishes. If it fails again, I'll pull Generated by Claude Code |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was a problem 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.
There was an error while loading. Please reload this page.
|
Ready for review at
Generated by Claude Code |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
Conflicts: - vex/discover/mod.rs: kept both main's ContestedRef/`contested` and this branch's UnpatchedCopy/`unpatched_copies` (structs, fields, finalize); `contest_within_locks` still runs before `contest_across_locks`, after main's new sbt extractor. - vex/discover/testing/golden.rs: import and render both `contested` and `unpatched_copies`. - vex/discover/yarn.rs: kept main's ClassicBlockSource match and classic_block_purl; main's #921 `file:` directory copies and the git copies now go through the shared `Discovery::unpatched_copy` rule instead of main's local post-filter loop (same diagnostic: names the lock entry and "file: directory"). Co-Authored-By: Claude <[email protected]>
|
bugbot run Generated by Claude Code |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was a problem 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.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
- `scan --prune --dry-run` previewed the vendor GC's manifest drop with a qualifier-strip relation while the wet pass used PurlKey, so NuGet case, PEP 503 and composer padding variants were pruned for real but not in the preview. Both now call vendor::unused_vendored_manifest_keys. - LockfileSupplement.purls is a HashSet<PurlKey> built once, so the lockfile-only predicate is one hash lookup instead of re-keying the whole set on every miss. - Ledgers::hosted_vendored_overlap deduplicates by PurlKey, so two spellings of one release give one takeover warning. - get's hosted-claim set (rebased onto #940's new code) is a HashSet<PurlKey>; the new gem takeover pin lookup uses PurlKey::same. - composer_version: pin that the sentinel-free key PurlKey uses never lets a rejected spelling collide with an accepted one, and document it. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Merges cleanly; additionally routes the yarn berry url-copy VEX justification (added on main in #940) through redact_url so a credentialed tarball URL never reaches the published VEX document. Co-Authored-By: Claude <[email protected]>
- `scan --prune --dry-run` previewed the vendor GC's manifest drop with a qualifier-strip relation while the wet pass used PurlKey, so NuGet case, PEP 503 and composer padding variants were pruned for real but not in the preview. Both now call vendor::unused_vendored_manifest_keys. - LockfileSupplement.purls is a HashSet<PurlKey> built once, so the lockfile-only predicate is one hash lookup instead of re-keying the whole set on every miss. - Ledgers::hosted_vendored_overlap deduplicates by PurlKey, so two spellings of one release give one takeover warning. - get's hosted-claim set (rebased onto #940's new code) is a HashSet<PurlKey>; the new gem takeover pin lookup uses PurlKey::same. - composer_version: pin that the sentinel-free key PurlKey uses never lets a rejected spelling collide with an accepted one, and document it. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
|
bugbot run |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
Resolve conflicts in vex/discover: keep main's same-lock contest (#940) alongside this branch's unwired-copy unattestation, pnpm bundled copies and berry registry-locator contest. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
There was a problem 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 acbac79. Configure here.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
After merging main's #940 same-lock unpatched-copy contest into the #828 shadowing, a pin withheld because a pnpm file: dir/tarball, a yarn classic registry/file: block, or a berry other-name file:/url copy installs beside it is shadowed and restored like any other pin. Extend the CLI contract sentence that only named bundled, git and hasShrinkwrap-nested copies. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
|
[agent] Merged at
Generated by Claude Code |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
Successfully merging this pull request may close these issues.
Yarn classic VEX attests not_affected when yarn.lock also has a registry block for the patched name@version (e.g. afteryarn add -W <pkg> --exact), though yarn installs only the unpatched registry copy
There was an error while loading. Please reload this page.