Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: SocketDev/socket-patch
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: c20619b
Choose a base ref
...
head repository: SocketDev/socket-patch
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 36d440e
Choose a head ref
  • 6 commits
  • 126 files changed
  • 2 contributors

Commits on May 27, 2026

  1. ci(release): adopt npm staged publishing via OIDC (#87)

    Switches the npm-publish job to `npm stage publish` so the GitHub
    Actions workflow uploads tarballs to npm's staging queue. A maintainer
    then approves each staged version with 2FA from npmjs.com or the npm
    CLI before it becomes installable.
    
    The previous direct-publish flow was failing with `OIDC permission
    denied for this action` against npm's post-2026-05-20 trusted-publisher
    rules, which require the allowed-action checkbox(es) to be explicit.
    Each of the 15 packages needs a trusted publisher configured on
    npmjs.com (SocketDev/socket-patch → release.yml) with both `npm publish`
    and `npm stage publish` allowed; the workflow uses stage-publish for
    every release.
    
    Workflow changes:
    - Bump actions/setup-node to v6.4.0 + package-manager-cache: false
      (eliminates the always-auth deprecation warning emitted by v4).
    - Replace `npm publish --provenance --access public` with
      `npm stage publish --access public`. OIDC trusted publishing emits
      provenance automatically, so --provenance is now redundant.
    - Collect successfully staged package names and write a step summary
      with org-dashboard and per-package review links, plus a ::notice::
      pointing at the staged-packages dashboard, so maintainers can click
      straight from the workflow run page into the approval UI.
    
    Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    mikolalysenko and claude authored May 27, 2026
    Configuration menu
    Copy the full SHA
    cfa554e View commit details
    Browse the repository at this point in the history
  2. refactor: dedupe ecosystem dispatch, telemetry, API client, cleanup, …

    …get (#88)
    
    * refactor: dedupe ecosystem dispatch, telemetry, API, cleanup, get/blob helpers
    
    Net ~718 lines removed across six files; all 1308 tests still pass.
    
    - ecosystem_dispatch.rs: macro-extract the 8 per-ecosystem scan blocks
      duplicated between find_packages_for_purls and find_packages_for_rollback;
      share a dispatch_find core with a pypi_merge callback for the only real
      divergence
    - commands/get.rs: hoist report_error / print_json / empty_result_json /
      report_fetch_failure / write_all_patch_blobs / vulnerabilities_for_manifest
      / build_patch_record; fold the three CVE/GHSA/PURL search arms into one
      dispatch
    - utils/telemetry.rs: replace ~18 hand-built HashMap<String, Value>
      constructions with a fire() helper plus serde_json::json!({...}) literals
    - api/client.rs: collapse search_patches_by_{cve,ghsa,package} behind a
      shared search_patches_by_route(route, identifier)
    - api/blob_fetcher.rs: derive Default for FetchMissingBlobsResult; share an
      all_failed_result helper for the three mkdir-blocker branches
    - utils/cleanup_blobs.rs: unify cleanup_unused_blobs / cleanup_unused_archives
      behind a cleanup_dir(dir, dry_run, is_used) core
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    
    * refactor(ecosystem_dispatch): hoist MergeFn type alias for clippy
    
    `-D clippy::type_complexity` rejected the inline fn-pointer signature on
    `dispatch_find`'s `pypi_merge` argument. Lift it to a `MergeFn` type alias
    shared by `merge_first_wins` and `merge_pypi_qualified`.
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    
    ---------
    
    Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    mikolalysenko and claude authored May 27, 2026
    Configuration menu
    Copy the full SHA
    3835974 View commit details
    Browse the repository at this point in the history

Commits on May 28, 2026

  1. test(args): regression coverage for BoolishValueParser on env bools (#89

    )
    
    Two new tests in cli_global_args.rs:
    
    - bool_env_vars_accept_one_and_yes: SOCKET_OFFLINE=1, SOCKET_GLOBAL=yes,
      SOCKET_JSON=on, etc. all parse as `true`. Pins the BoolishValueParser
      wiring we just added — without it clap fails with
      `error: invalid value '1' for '--offline'` (the bug that prompted
      the fix).
    - bool_env_vars_reject_zero_and_falsey: SOCKET_OFFLINE=0,
      SOCKET_DEBUG=false, SOCKET_TELEMETRY_DISABLED=no, SOCKET_JSON=off
      all parse as `false`. Guards against an over-eager parser flipping
      a bool on any non-empty string.
    
    Both new tests + the existing env_vars_populate_global_args are now
    `#[serial]` — env-var state is process-global, so parallel test
    runs race the cleanup. Without serialization the negative-case test
    flakes by inheriting `SOCKET_OFFLINE=1` from the positive case.
    
    Assisted-by: Claude Code:opus-4-7
    mikolalysenko authored May 28, 2026
    Configuration menu
    Copy the full SHA
    f97167d View commit details
    Browse the repository at this point in the history
  2. feat(pypi): narrow/broad release breadth + multi-variant remove/rollb…

    …ack fixes (#90)
    
    PyPI is the only ecosystem that carries a Socket-specific `artifact_id`
    PURL qualifier, so a single `package@version` can resolve to several
    patch variants (one per wheel/sdist release). Only the installed
    distribution can ever apply, but scan/get downloaded every variant and
    remove/rollback mishandled the qualified keys.
    
    Feature — download-time release breadth (narrow default):
    - Add `--all-releases` (env `SOCKET_ALL_RELEASES`, default off) to `scan`
      and `get`. Narrow keeps only the variant matching the installed
      distribution; broad keeps every variant (portable across environments).
    - `select_installed_variant` (core `patch/apply.rs`) picks the variant
      whose first patched file is Ready/AlreadyPatched against the on-disk
      package — shared by the narrow filter and rollback dedupe.
    - `filter_to_installed_releases` (commands/get.rs) runs in the shared
      download path; non-PyPI ecosystems and single-variant packages pass
      through untouched. Falls back to broad (with a warning surfaced in the
      JSON `warnings` array) when the package is not installed or no variant
      matches the on-disk bytes.
    
    Correctness fixes surfaced by multi-release manifests:
    - Base-PURL matching (`purl_matches_identifier`, core utils/purl.rs):
      `remove`/`rollback` of a base PURL now affect every release variant;
      a qualified PURL or UUID still targets exactly one. Previously a base
      PURL matched nothing because manifest keys are qualified.
    - Rollback variant dedupe: rollback groups discovered packages by base
      PURL and rolls back only the installed-dist variant, ending the
      spurious HashMismatch failures that broad manifests would have caused
      (the non-installed variants resolve to the same on-disk file).
    - `remove` lists each variant when a base PURL expands, so the blast
      radius is visible before confirmation.
    - `detect_prunable` compares on stripped base PURLs, so
      `scan --all-releases --sync` no longer prunes the very variants it just
      downloaded.
    
    Tests:
    - New in_process_pypi_multi_release.rs: real `pip install six` + a
      three-variant wiremock exercising narrow-keeps-one, broad-keeps-all,
      remove-base-clears-all-and-rolls-back, and rollback-all-succeeds.
    - Unit tests for purl_matches_identifier, find_patches_to_rollback,
      remove_patch_from_manifest, detect_prunable (PyPI keep/prune), and
      `--all-releases` parse defaults for scan + get.
    
    Full workspace suite: 1573 passed, 0 failed; clippy clean.
    
    Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    mikolalysenko and claude authored May 28, 2026
    Configuration menu
    Copy the full SHA
    c182e72 View commit details
    Browse the repository at this point in the history
  3. feat(gem,maven): extend multi-platform release patching to RubyGems +…

    … Maven (#91)
    
    Generalizes the PyPI multi-release machinery (release-variant qualifiers,
    narrow/broad download, base-PURL remove/rollback) to the other ecosystems
    that ship multiple platform/release artifacts per package@version:
    
      * RubyGems — platform gems (`?platform=x86_64-linux`, `?platform=arm64-darwin`)
      * Maven    — classifier jars (`?classifier=linux-x86_64&ext=jar`)
    
    NuGet/npm/Cargo/Go/Composer/Deno are unaffected: they ship one artifact per
    version (platform splits live under separate package names), so they keep the
    1:1 PURL match path.
    
    Shared generalization:
    - Ecosystem::supports_release_variants() (Pypi | Gem | Maven) replaces the
      scattered `== Ecosystem::Pypi` gates in apply/get/dispatch.
    - ecosystem_dispatch: rename pypi-specific dedup_pypi_purls/merge_pypi_qualified
      to dedup_qualified_purls/merge_qualified and apply them to the gem and maven
      scan blocks. The crawler is queried with base PURLs and the installed variant
      is resolved by hashing on-disk files — the same model PyPI uses.
    - select_installed_variant -> plural select_installed_variants returning ALL
      present-and-matching variants. PyPI/RubyGems install exactly one distribution
      per environment (≤1 match, unchanged), but Maven classifier jars coexist in
      one version dir, so several may match. apply.rs applies every matching variant
      (no early `break`); the get narrow-filter and rollback dedupe keep all matches.
    
    RubyGems:
    - RubyCrawler::parse_dir_name_version now splits at the first dash-digit and
      drops the trailing `-<platform>` suffix, fixing a misparse that folded the
      platform into the version (`nokogiri-1.16.5-x86_64-linux` -> version
      `1.16.5-x86_64-linux`). New locate_gem_dir resolves a base name/version to the
      installed platform-suffixed gem directory.
    
    Maven needs no crawler change: find_by_purls already emits the base PURL keyed
    to the version directory, and each classifier variant is hash-resolved against
    its jar file. Maven stays behind SOCKET_EXPERIMENTAL_MAVEN and still leaves
    `.jar.sha1` sidecars stale (no fixup — unchanged).
    
    Tests:
    - in_process_gem_multi_platform.rs: synthetic platform gem (no `gem` binary) +
      wiremock — narrow keeps the installed platform, broad keeps all, remove base
      PURL clears all variants and rolls back, rollback-all exits 0.
    - in_process_remote_ecosystems_apply.rs: maven_multi_classifier test proving the
      plural selector patches every coexisting classifier jar.
    - Unit tests for gem dir-name platform parsing (incl. the regression case and a
      trailing-OS-version platform) and the supports_release_variants predicate.
    
    Full workspace suite: 1580 passed, 0 failed; clippy clean.
    
    Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    mikolalysenko and claude authored May 28, 2026
    Configuration menu
    Copy the full SHA
    d1108cb View commit details
    Browse the repository at this point in the history

Commits on May 29, 2026

  1. fix: repo-wide correctness, security & filesystem-safety hardening pa…

    …ss (v3.2.0) (#92)
    
    * fix: repo-wide correctness, security & filesystem-safety hardening pass (v3.2.0)
    
    Reviewed every source file in both crates line by line, fixed the bugs
    found, and added regression tests throughout. Highlights:
    
    Security
    - patch/package.rs: path-traversal via validate-before-normalize
      (package//etc/passwd escaped the package tree)
    - patch/diff.rs: clamp unbounded Vec preallocation from untrusted
      bsdiff target-size header (OOM/abort on a hostile delta)
    - vex/verify.rs: omit zero-file patches instead of emitting an
      evidence-free not_affected attestation
    
    Filesystem safety / atomicity / rollback
    - apply: DirWriteGuard for read-only dirs, chown-before-chmod to keep
      setuid/setgid, parent-dir fsync after rename
    - cow: atomic rename-over symlink (no pre-unlink), stage cleanup
    - rollback: delegate to hardened apply_file_patch; AlreadyOriginal
      before blob check; read-only-dir new-file delete
    - file_hash/git_sha256: open-once + fstat (TOCTOU), regular-file guard,
      size/body mismatch detection
    - cargo/nuget sidecars: hardened writes/deletes in read-only caches
    - cleanup_blobs: symlink-tolerant, accurate counts
    - apply_lock: classify genuine flock errors as Io, clamp timeout sleep
    
    Crawlers (on-disk layout & metadata)
    - composer v-prefix + malformed-entry tolerance + on-disk check
    - go cache-at-root, version case-encoding, GOPATH list, module directive
    - npm symlink following + nested-recursion guard
    - nuget global-cache version casing
    - python macOS framework layout + dist-info dir-name fallback
    - deno macOS cache path, XDG_CACHE_HOME, empty DENO_DIR
    - maven XML-comment stripping + skip-section depth
    - cargo TOML header tolerance + dir-name version split
    - shared utils/fs::entry_is_dir follows symlinks
    
    API client, commands & misc
    - proxy-url override on binary downloads; deterministic org/title/batch
      flag; case-insensitive hash compare
    - USER_AGENT + telemetry version track CARGO_PKG_VERSION (was 1.0.0)
    - apply release-variant NotFound spurious-failure fix
    - get/scan/remove char-safe truncation (UTF-8 panic)
    - setup/repair honest non-zero exit codes + telemetry
    - rollback no-op miscount; unlock released-snapshot; vex qualified PURLs
    - package.json non-object/dedup/glob/key-order (preserve_order)
    - json_envelope status invariant + oldUuid; list ordering; fuzzy_match
      tie-break; lock_cli sub-second timeout; vex schema/product fixes
    
    Updated stale repair/python_crawler e2e expectations to the corrected
    contracts. Bumped version to 3.2.0 and added the scripts/study-crates.ts
    audit harness used to drive the review.
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    
    * test: fix Windows-only file_hash directory-rejection assertion
    
    `File::open` on a directory fails outright on Windows (different OS error
    kind), whereas on Unix it opens and the is_file() guard rejects it with
    InvalidInput. The production code rejects directories on both platforms;
    only pin the specific InvalidInput kind off-Windows.
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    
    ---------
    
    Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    mikolalysenko and claude authored May 29, 2026
    Configuration menu
    Copy the full SHA
    36d440e View commit details
    Browse the repository at this point in the history
Loading