Skip to content

fix: correctness bug sweep + hardening tests across crawlers, patch, and vex#106

Merged
Mikola Lysenko (mikolalysenko) merged 4 commits into
mainfrom
fixes/correctness-and-hardening-sweep
Jun 8, 2026
Merged

fix: correctness bug sweep + hardening tests across crawlers, patch, and vex#106
Mikola Lysenko (mikolalysenko) merged 4 commits into
mainfrom
fixes/correctness-and-hardening-sweep

Conversation

@mikolalysenko

Copy link
Copy Markdown
Collaborator

Summary

A broad sweep of correctness, security, and atomicity bug fixes surfaced by a line-by-line review of the codebase, each paired with regression tests (many RED-verified without the fix).

Crawlers

  • Single-quote TOML parsing (cargo crawler dropped name = 'serde')
  • Composer case canonicalization for PURLs / lookups
  • Vendor-before-project-gate ordering (cargo/nuget scanning non-matching trees)
  • Yarn PnP .pnp.js detection
  • NuGet legacy content-folder + local-mode gating
  • Maven skip-section prefix boundary handling
  • Python crawler layout/metadata fallbacks (bare python3, lib64, body-bleed)

Patch engine

  • Path-escape guards: cargo/go redirect coordinate traversal, rollback delete, cargo sidecar read
  • Atomic writes for user-owned manifests: go.mod, Cargo.toml, .cargo/config.toml, package.json, pyproject.toml/requirements.txt
  • bsdiff header validation (forged block-length panic, unbounded prealloc)
  • copy_tree symlink chmod, cow hardlink is_file guard
  • Lock acquire timeout overflow panic

VEX

  • Single-quote product detection
  • Schema / verify / conformance hardening

API client

  • fetch_binary auth error classification (401/403/429 → auth fallback)
  • Token shape + org slug validation

Misc

  • PURL subpath strip leak
  • Manifest deterministic (sorted) serialization + empty-setup omission
  • Severity color ordering (critical vs high)
  • cleanup_blobs orphan handling
  • pth_hook detection + non-atomic write fixes

Test plan

  • cargo test across feature combos
  • CI green

🤖 Generated with Claude Code

…and vex

Fixes a broad set of correctness, security, and atomicity bugs surfaced by
a line-by-line review, each paired with regression tests:

- crawlers: single-quote TOML parsing, case canonicalization, vendor/project
  gate ordering, PnP detection, NuGet legacy/local-mode gating, Maven skip-
  section boundaries, Python layout/metadata fallbacks
- patch: path-escape guards (cargo/go redirect, rollback, sidecars), atomic
  writes for user manifests (go.mod, Cargo.toml, .cargo/config.toml,
  package.json, pyproject/requirements), bsdiff header validation, copy_tree
  symlink chmod, cow hardlink is_file guard, lock timeout overflow
- vex: single-quote product detection, schema/verify hardening
- api/client: fetch_binary auth error classification, token/slug validation
- misc: purl subpath strip, manifest deterministic serialization, severity
  color ordering, cleanup_blobs orphan handling, pth_hook detection fixes

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Three CI-blocking fixes surfaced by the failing checks (clippy + test on
all OSes + coverage + test-release):

- clippy: `map_or(true, ..)` -> `is_none_or(..)` in manifest/schema.rs
  (clippy 1.93 `unnecessary_map_or`, denied via `-D warnings`).

- rollback_dispatch_branch_golang: the sweep added a project-local go
  redirect rollback backend. In local mode go rolls back by dropping the
  `replace` redirect and leaves the module cache pristine, so it never
  restores cache bytes (verified: local mode reports success without
  touching the file; global mode genuinely restores). The dispatch test's
  byte-restore contract only holds on the in-place/global path — the go
  analog of the cargo test's `vendor/` in-place layout — so drive that one
  fixture in `--global` mode.

- output_helpers_e2e: the sweep's severity-colour-inversion fix flipped
  critical->bright-red(91)/high->red(31) and updated the in-crate unit
  tests, but this integration file still asserted the old swapped codes.
  cargo test is fail-fast, so it aborted on the golang failure before ever
  reaching this binary in CI; surfaced via a local `--no-fail-fast` run.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
`manifest_path_through_regular_file_reports_unreadable_via_binary` nested
the manifest under a regular file (`<file>/manifest.json`), assuming the OS
rejects the read with a non-absence error. That holds on Unix (ENOTDIR) but
NOT on Windows, where traversing through a file is `ERROR_PATH_NOT_FOUND`
(NotFound) — legitimately classified as `manifest_not_found`, failing the
assertion on windows-latest.

Point the manifest path at a directory instead: reading it fails with a
non-NotFound error on every platform (Unix `IsADirectory`, Windows
`PermissionDenied`), so the "present-but-unreadable → manifest_unreadable"
contract is exercised portably. Renamed accordingly.

This was masked on the first push: cargo test is fail-fast and the Windows
run aborted at this binary (sorts before the now-fixed golang/output tests).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
`test_find_recurses_into_nested_workspace` matched walked filesystem paths
with `str::ends_with("packages/inner/package.json")`, which fails on Windows
where `WalkDir` yields `\`-separated paths. Match on the `PathBuf` via
`Path::ends_with`, which compares whole components and accepts `/` in the
pattern on every platform (Windows treats both `/` and `\` as separators).

This is the only walked-real-path assertion that used a forward-slash string
literal; the CLI/manifest path assertions elsewhere operate on
forward-slash-normalized manifest keys (echoed verbatim) and are unaffected.

Surfaced by fail-fast: the Windows run aborted here (socket-patch-core --lib)
only after the previously-fixed cli_parse_list binary passed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@mikolalysenko Mikola Lysenko (mikolalysenko) merged commit 4d5ba3d into main Jun 8, 2026
54 checks passed
@mikolalysenko Mikola Lysenko (mikolalysenko) deleted the fixes/correctness-and-hardening-sweep branch June 8, 2026 20:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants