URI::PackageURL 2.26 released: PURL and VERS for Perl

URI::PackageURL 2.26 is on CPAN.

URI-PackageURL implements two specifications that are becoming central to software supply-chain security:

  • PURL (Package URL, standardized as ECMA-427): a uniform way to identify a software package across ecosystems (pkg:cpan/URI-PackageURL@2.26)
  • VERS (Version Range): a universal notation for version ranges (vers:cpan/>=2.00|<2.26)

It ships with two CLI tools, purl-tool and vers-tool, and depends only on core modules.

What's new

The new cpan PURL type

The main change is support for the updated cpan type definition in purl-spec.

Until now a cpan PURL required the author as namespace (pkg:cpan/TIMB/DBI@1.643). The problem is that the author of a distribution can change over time. DBI is a good example: 1.643 was released by TIMB, 1.644 by HMBRAND. With the author in the namespace the two releases end up under different identifiers, and pkg:cpan/TIMB/DBI and pkg:cpan/HMBRAND/DBI look like two different packages. Often a tool only knows the distribution name and version anyway.

With the new definition:

  • the namespace is optional, so pkg:cpan/DBI@1.644 is a valid PURL
  • the preferred way to specify the author is the new author qualifier: pkg:cpan/DBI@1.644?author=HMBRAND
  • a new distpath qualifier holds the path of the archive on CPAN, for distributions that don't follow the usual layout: pkg:cpan/Term-Gnuplot@0.90380906?distpath=authors%2Fid%2FI%2FIL%2FILYAZ%2Fmodules%2FTerm-Gnuplot-0.90380906.zip
  • the namespace form is still valid for compatibility with existing tools
  • the name must still be the distribution name, never a module name (URI::PackageURL is rejected)

purl_to_urls and purl-tool --download-url build the download URL from author or distpath:

$ purl-tool 'pkg:cpan/DBI@1.644?author=HMBRAND' --download-url
https://www.cpan.org/authors/id/H/HM/HMBRAND/DBI-1.644.tar.gz

This matters for vulnerability data. Since CVE Record Format 5.2.0, the affected section of a CVE record can include a packageURL. The schema says it MUST NOT include a version, because affected versions go in the versions array. CPANSec plans to use this field for CPAN distributions. With the old cpan type the identifier would have been pkg:cpan/TIMB/DBI, which says nothing about releases by HMBRAND. With the new type it is simply pkg:cpan/DBI. NixOS will adopt the same format.

If you produce cpan PURLs (SBOM generators, advisory databases), consider moving to ?author=, or dropping the author entirely when you don't have it.

PURL

  • Validation is now enabled by default in URI::PackageURL->from_string and decode_purl. Use validate => 0 to turn it off.
  • New is_purl utility
  • UTF-8 support (RFC 3629) in components and in purl-tool input/output
  • Improved component validation and percent-encoding
  • About 39% faster URI::PackageURL::Type

VERS

  • New is_vers utility and scheme validation
  • New bundled comparators: semver, npm, intdot, lexicographic and datetime. The scheme class is now used by contains, by to_string (to sort constraints), by version_compare and by from_native.
  • Percent-encoding now follows the vers-spec canonical form, with UTF-8 support
  • Fixes: vers:none/* (which matches no versions), alpm/pypi versions being compared as SemVer, and an empty version in a constraint
  • The npm/semver native range conversion now intersects space-separated comparators and croaks on unsatisfiable ranges:

    URI::VersionRange->from_native(scheme => 'npm', range => '>=5.0.3 >=4.2.1'); # vers:npm/>=5.0.3

Bring your own comparator

Version comparison differs between ecosystems, so comparators are pluggable. Write a URI::VersionRange::Scheme::<scheme> class, and contains and sorting will use it automatically:

package URI::VersionRange::Scheme::rpm {
    use RPM4;
    use parent 'URI::VersionRange::Version';
    use overload ('cmp' => \&compare, '<=>' => \&compare, fallback => 1);
    sub compare { rpmvercmp($_[0]->[0], $_[1]->[0]) }
}

PURL and VERS spec compliance

The distribution is tested against the official purl-spec and vers-spec test suites.

Links

  • MetaCPAN: https://metacpan.org/dist/URI-PackageURL
  • GitHub: https://github.com/giterlizzi/perl-URI-PackageURL
  • Changes: https://metacpan.org/dist/URI-PackageURL/changes

Enjoy!

Leave a comment

About Giuseppe Di Terlizzi

user-pic I blog about Perl.