Skip to content

Read Cargo.toml package name and version through one shared toml_edit reader #693

Description

[agent] Filed by the scheduled architecture audit routine (ecosystems and formats). Register: E15.

Kind: refactor. Source: review §1 recommendation 1 and Part 5.4 ("Cargo"); register E15.

Problem

Five places read a Cargo.toml [package] table, with three different parsers. Two of them are hand-rolled line scanners, although toml_edit is already a dependency of socket-patch-core.

Reader Parser Used for
crawlers/cargo_crawler.rs#L12-L113:`` parse_cargo_toml_name_version + `parse_table_header` + `extract_string_value` line scanner ("no TOML crate dependency") crate identity in crawl_all (#L399-L407) and find_by_purls (#L285-L302)
vex/product.rs#L167-L170 parse_cargo_toml → scan_toml_section a second line scanner (also used for pyproject.toml) the VEX product purl
vendor/cargo_tag.rs#L132-L155 version_literal toml_edit, [package] or legacy [project] tagging the vendored copy's version
vendor/cargo.rs#L1665-L1680 path_crate_version toml_edit, [package] only the version a [patch] path points at
vendor/cargo.rs#L82-L101 declared_cargo_minor toml_edit, ad hoc .get("package").get("rust-version") the declared cargo floor

They have drifted. I ran one set of manifests through the crawler, VEX product detection and cargo_tag on 045d7ec, in a throwaway integration test that I ran twice and did not commit. toml_edit parses all of these inputs:

Cargo.toml crawler VEX product cargo_tag
[package] name/version ("old", "0.1.0") pkg:cargo/old@0.1.0 tags it
same, with a UTF-8 BOM None pkg:cargo/old@0.1.0 (strips the BOM) tags it
legacy [project] table None None tags it
dotted keys (package.name = …) None None tags it
[package] junk (invalid TOML) ("old", "0.1.0") None refuses (Unparseable)

So a crate whose manifest cargo_tag reads can be invisible to the crawler, and the crawler accepts a manifest that cargo rejects. In a cargo vendor directory the crawler's fallback (the directory name) carries no version, so such a crate cannot be discovered at all. The VEX scanner and the crawler also disagree with each other on BOMs.

Normalized crates.io manifests always use a plain [package] table, so real registry crates hit none of these rows today. The point of this issue is the duplicate parsers and the rules that have already drifted, not a live wrong answer.

Symptoms

Impact: low risk, small size. Deleting the hand-rolled scanner removes a class of "valid TOML the scanner misreads" bugs (the crawler has already needed fixes for header comments and single quotes, according to its own comments).

Proposed change

Add one pure reader in formats/cargo/manifest.rs (or formats/cargo/mod.rs), built on toml_edit:

pub(crate) struct PackageFields { name: Option<String>, version: Inherit<String>, rust_version: Inherit<String>, workspace: Option<String> }
pub(crate) enum Inherit<T> { Literal(T), Workspace, Absent }
pub(crate) fn package_fields(doc: &DocumentMut) -> Option<PackageFields>   // [package], else legacy [project]

Then:

  • Delete parse_cargo_toml_name_version, parse_table_header and extract_string_value from cargo_crawler.rs (about 100 lines plus their unit tests). The crawler parses with toml_edit (BOM handled by the parser) and keeps its directory-name fallback for Inherit::Workspace. tests/crawler_cargo_e2e.rs and cargo_crawler/oracle.rs switch to the shared reader.
  • vex/product.rs parse_cargo_toml uses package_fields (scan_toml_section stays for pyproject.toml, which is E38's).
  • cargo_tag::version_literal takes its item from the shared lookup and keeps only the span and quote logic.
  • path_crate_version uses the shared reader. Its [project] blind spot goes away.

plan_cargo_toml's regex dependency scanner in patch/redirect/mod.rs is the other half of E15. It is out of scope here and will be filed separately.

Size and scope

Acceptance criteria

  • One [package] reader in formats/cargo. No hand-rolled TOML scanner reads Cargo.toml in crawlers/ or vex/product.rs.
  • A table test over the rows above (plain, BOM, [project], dotted keys, inline package = { … }, version.workspace = true, invalid TOML): crawler, VEX product and cargo_tag agree on every row.
  • version.workspace = true still falls back to the directory name in the registry layout (existing crawler tests).
  • Green: cargo test -p socket-patch-core (crawler_cargo_e2e, the cargo_crawler oracle, vex::product, vendor::cargo_tag, vendor::cargo) and cargo clippy --workspace --all-targets.

Dependencies

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    agent:triagedarch-auditFiled by a scheduled architecture audit routine (see the architecture review discussion)pm:cargoCargopriority:p2refactorStructural change: duplicated code or logic, missing abstraction, layering, dead code

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions