GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — fix(vendor): accurate refusals for bundled/alias/CRLF lock shapes by mikolalysenko · Pull Request #185 · SocketDev/socket-patch

Conversation

@mikolalysenko

@mikolalysenko Mikola Lysenko (mikolalysenko) commented Aug 14, 2026 •
edited by cursor Bot
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Collaborator

Problem

Three vendored-mode diagnostics defects from the 2026-08-13 audit sent users down the wrong remediation path or silently hid security-relevant facts:

  1. npm: all-bundled/all-link target refuses with a misleading "not found" and drops the UNPATCHED advisories (medium). When every lock instance of the target is bundled inside a parent's tarball (inBundle) or a link, scan_lock_matches returns zero rewritable matches and vendor_npm refused with the generic vendor_lock_entry_not_found ("make sure the package is installed and locked (npm install)"). The entry IS in the lock, npm install cannot help, and because VendorOutcome::Refused has no warnings channel, the per-instance "that copy stays UNPATCHED" advisories were silently discarded. Concrete scenario: a lock whose only [email protected] entries are an inBundle: true nested copy and a workspace link — the user is told the package isn't installed instead of being told it cannot be patched by vendoring and remains vulnerable.

  2. npm v2 legacy dependencies mirror: bundled nodes wrongly rewritten, alias consumers silently unpatched (low). rewrite_legacy_tree rewrote bundled: true nodes (the packages scan skips their inBundle twins, so the two lock halves desynced — npm never installs a bundled copy from resolved), and alias consumers ("alias": {"version": "npm:[email protected]"}) matched neither key nor version, so npm 6 clients reading the mirror keep installing the unpatched registry bytes through the alias with zero warning.

  3. pnpm: CRLF lockfile refuses with a misleading "not found" (low). A CRLF pnpm-lock.yaml (Windows autocrlf checkout) passes check_lock_version (str::lines strips \r) but breaks every structural probe (split_lines keeps the trailing \r, so packages: never matches "packages:\r"), surfacing as vendor_lock_entry_not_found — wrong diagnosis for a lock pnpm itself accepts.

Fix

  • vendor_npm: when matches is empty but the scan pushed vendor_bundled_instance_skipped / vendor_link_entry_skipped warnings, refuse with the new vendor_lock_entry_not_rewritable code whose detail carries the per-instance stays-UNPATCHED advisories verbatim and explicitly says npm install will not help. The genuinely-absent case keeps the existing vendor_lock_entry_not_found. Both codes remain non-benign (refusal_is_benign unchanged), so exit behavior is unchanged.
  • rewrite_legacy_tree: skips bundled: true nodes (parity with the packages scan's inBundle skip) and emits a loud vendor_legacy_alias_skipped warning for alias consumers, naming the JSON-pointer node and that npm 6 still installs UNPATCHED bytes through it. Aliases are warned rather than rewritten because the legacy alias spelling has no proven equivalent rewrite — fail loud, not fail open.
  • vendor_pnpm: fails closed immediately after the version sniff with the new vendor_lockfile_crlf_unsupported refusal, naming the CRLF line endings and the LF-normalization remedy, before any structural probe can produce the wrong diagnosis.

Skipped (out of lane scope, third gap of the low-severity legacy-mirror finding): recomputing the legacy node's requires map from the patched manifest. A correct recompute needs the staged patched package.json plumbed into rewrite_legacy_tree plus a proven mapping to npm 6's requires grammar; doing it without a spike risks corrupting v2 locks for a purely npm-6-era reader.

Testing

  • New regression tests, each verified red against the pre-fix behavior (guards temporarily neutralized) before going green:
    • npm_lock.rs::tests::all_bundled_or_link_instances_refuse_with_accurate_reason
    • npm_lock.rs::tests::v2_legacy_bundled_node_is_not_rewritten
    • npm_lock.rs::tests::v2_legacy_alias_node_warns_and_keeps_registry_resolution
    • pnpm_lock.rs::tests::crlf_lock_refuses_naming_line_endings
  • cargo test -p socket-patch-core --lib — 2079 passed
  • cargo test -p socket-patch-cli --test in_process_vendor — 27 passed
  • cargo test -p socket-patch-cli --test e2e_vendor_npm_build — 7 passed
  • cargo test -p socket-patch-cli --test e2e_vendor_pnpm_build — passed

🤖 Generated with Claude Code


Note

Medium Risk
Changes vendor lock rewrite and refusal paths that affect which lock bytes are edited and what users see when patches cannot apply; incorrect behavior could leave unpatched installs or mislead remediation, but scope is diagnostic/parity fixes with targeted tests.

Overview
Improves npm and pnpm vendoring diagnostics when lock entries exist but cannot be rewritten, so users are not told to run npm install / pnpm install incorrectly and security-relevant UNPATCHED facts are not dropped.

For npm, when every matching lock instance was skipped (bundled inBundle or link), refusal now uses vendor_lock_entry_not_rewritable with bundled/link skip details in the message instead of vendor_lock_entry_not_found. The v2 legacy dependencies mirror now skips bundled: true nodes (aligned with packages inBundle) and emits vendor_legacy_alias_skipped for npm:name@ver alias nodes left at registry resolution for npm 6 readers.

For pnpm, CRLF pnpm-lock.yaml is rejected up front with vendor_lockfile_crlf_unsupported and LF normalization guidance before structural parsing can misdiagnose a missing package entry.

Regression tests cover all-bundled/link refusal, legacy bundled skip, legacy alias warning, and CRLF refusal.

Reviewed by Cursor Bugbot for commit 03fe6cd. Configure here.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@mikolalysenko @claude
fix(vendor): accurate refusals for bundled/alias/CRLF lock shapes
03fe6cd
Three diagnostics fixes so vendored-mode refusals name the real cause
instead of sending users down the wrong remediation path:

- npm: when every lock instance of the target is bundled inside a
  parent's tarball or a link, vendoring refused with the generic
  vendor_lock_entry_not_found ("run `npm install`" -- which cannot
  help) and silently dropped the stays-UNPATCHED advisories, since a
  Refused outcome has no warnings channel. It now refuses with
  vendor_lock_entry_not_rewritable and carries the per-instance
  UNPATCHED advisories in the refusal detail.

- npm v2 legacy `dependencies` mirror: `bundled: true` nodes are no
  longer rewritten (parity with the packages scan's inBundle skip --
  npm never installs a bundled copy from `resolved`, and rewriting it
  desynced the two lock halves), and alias consumers
  (`"alias": {"version": "npm:real@ver"}`) now emit a loud
  vendor_legacy_alias_skipped warning: npm 6 reading the mirror still
  installs the unpatched registry bytes through the alias.

- pnpm: a CRLF pnpm-lock.yaml (Windows autocrlf checkout) passed the
  version sniff but failed every structural probe, surfacing as the
  misleading vendor_lock_entry_not_found. It now fails closed up
  front with vendor_lockfile_crlf_unsupported, naming the line
  endings and the LF-normalization remedy.

Co-authored-by: Claude Fable 5 <[email protected]>
Wenxin-Jiang
Wenxin Jiang (Wenxin-Jiang) approved these changes Aug 14, 2026
View reviewed changes
@mikolalysenko
Mikola Lysenko (mikolalysenko) merged commit f368573 into main Aug 14, 2026
231 of 234 checks passed

Uh oh!

There was an error while loading. Please reload this page.

@mikolalysenko
Mikola Lysenko (mikolalysenko) deleted the fix/vendor-refusal-diagnostics branch August 14, 2026 20:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@Wenxin-Jiang Wenxin Jiang (Wenxin-Jiang) Wenxin-Jiang approved these changes

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

None yet

Projects

None yet

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.

2 participants

@mikolalysenko @Wenxin-Jiang
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.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.