From 9ac62ecd610df82312d4c396de11b446f94ce249 Mon Sep 17 00:00:00 2001 From: Samuel Dionne-Riel Date: Wed, 8 Apr 2026 14:09:28 -0400 Subject: [PATCH 1/6] doc/meta: Reword *logical values* for CPEs The original wording missed the *not meaningful* nuance, and adding an `or` clause within the sentence would have made it hard to understand. Instead, it is now split into a list, and ordered in the same order as found in `5.3.1` in NISTIR 7695. The logical name used by the specification (ANY/NA) was also added. --- doc/stdenv/meta.chapter.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/doc/stdenv/meta.chapter.md b/doc/stdenv/meta.chapter.md index 1e1e190b3eda..285211a401da 100644 --- a/doc/stdenv/meta.chapter.md +++ b/doc/stdenv/meta.chapter.md @@ -296,7 +296,10 @@ Some of them are as follows: You can find information about all of these attributes in the [official specification](https://csrc.nist.gov/projects/security-content-automation-protocol/specifications/cpe/naming) (heading 5.3.3, pages 11-13). -Any fields that don't have a value are set to either `-` if the value is not available or `*` when the field can match any value. +Any fields that don't have a value are set to either: + +* `*` (ANY) when the field can match any value +* `-` (NA) when the value is not meaningful or not used in the description For example, for glibc 2.40.1 CPE would be `cpe:2.3:a:gnu:glibc:2.40:1:*:*:*:*:*:*`. From e52e23f041e6802d5695258d61eb184428dab1cc Mon Sep 17 00:00:00 2001 From: Samuel Dionne-Riel Date: Wed, 8 Apr 2026 13:48:37 -0400 Subject: [PATCH 2/6] doc/meta: Fix documentation for `edition` CPE field MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The field could have been simply removed from the list, as it is not used, but it should be present in that form at least for *some undefined* length of time to present as a correction for anyone using the `edition` field mistakenly. My claim comes from the literal source listed in the next paragraph (NISTIR 7695), the first few words of `5.3.3.6` are: > The edition attribute is considered deprecated Thus we consider it deprecated. Furthermore the section documents that it should be using the value `ANY`. It could be considered debatable as `NA` should be used “when there is no legal or meaningful value for that attribute, or when that attribute is not used as part of the description”... But the spec states that `ANY` should be used, so we state `ANY` should be used. --- doc/stdenv/meta.chapter.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/stdenv/meta.chapter.md b/doc/stdenv/meta.chapter.md index 285211a401da..d1823717b4b8 100644 --- a/doc/stdenv/meta.chapter.md +++ b/doc/stdenv/meta.chapter.md @@ -292,7 +292,7 @@ Some of them are as follows: * *product* - name of the package * *version* - version of the package * *update* - name of the latest update, can be a patch version for semantically versioned packages -* *edition* - any additional specification about the version +* *edition* - deprecated and should be set to `*` You can find information about all of these attributes in the [official specification](https://csrc.nist.gov/projects/security-content-automation-protocol/specifications/cpe/naming) (heading 5.3.3, pages 11-13). From 8b81adddcd447992f404ce8678ce011ba000034f Mon Sep 17 00:00:00 2001 From: Samuel Dionne-Riel Date: Wed, 8 Apr 2026 13:55:08 -0400 Subject: [PATCH 3/6] doc/meta: Fix documentation and example for `update` CPE field The previous claims are unsourced, since they are not supported by the source given for CPEs. Quoting from the 5.3.3.5 section of the NISTIR 7695 document: > Values for this attribute SHOULD be vendor-specific alphanumeric > strings characterizing the particular update, service pack, or > point release of the product. So, first, they should be ***vendor-specific***, and dare I say, vendor-specified. But let's not trip on the carpet's flower pattern, and instead look at evidence from data. Using the data from `official-cpe-dictionary_v2.3.xml`, gently massaged into a form that can be queried, we can list all known CPE expressions for glibc. There is only one known entry using the `update` field. It's: ``` cpe:2.3:a:gnu:glibc:2.0.5:b:*:*:*:*:*:* ``` As such, the current example is plainly and demonstrably wrong. ``` SELECT * FROM cpe WHERE cpe_update != '' AND cpe_vendor = 'gnu' AND cpe_product = 'glibc' ORDER BY cpe_vendor, cpe_product, cpe_version id |title |cpe_part|cpe_vendor|cpe_product|cpe_version|cpe_update|cpe_edition|cpe_language|cpe_sw_edition|cpe_target_sw|cpe_target_hw|cpe_other| ------+-----------------+--------+----------+-----------+-----------+----------+-----------+------------+--------------+-------------+-------------+---------+ 460867|GNU glibc 2.0.5 B|a |gnu |glibc |2.0.5 |b | | | | | | | ``` Let's see good examples of `cpe_product` in contrast: ``` SELECT * FROM cpe WHERE cpe_update != '' AND cpe_vendor = 'gnu' AND cpe_product = 'bash' ORDER BY cpe_vendor, cpe_product, cpe_version DESC LIMIT 10 id |title |cpe_part|cpe_vendor|cpe_product|cpe_version|cpe_update|cpe_edition|cpe_language|cpe_sw_edition|cpe_target_sw|cpe_target_hw|cpe_other| ------+--------------------------------------------------------------+--------+----------+-----------+-----------+----------+-----------+------------+--------------+-------------+-------------+---------+ 460088|GNU Bourne-Again SHell bash (GNU Bash) 4.3.30 Beta 1 |a |gnu |bash |4.3.30 |beta1 | | | | | | | 460086|GNU Bourne-Again SHell bash (GNU Bash) 4.2.53 Beta 1 |a |gnu |bash |4.2.53 |beta1 | | | | | | | 460081|GNU Bourne-Again SHell bash (GNU Bash) 3.2.57 Beta 1 |a |gnu |bash |3.2.57 |beta1 | | | | | | | 460140|GNU Bourne-Again SHell bash (GNU Bash) 5.2 |a |gnu |bash |5.2 |- | | | | | | | 460141|GNU Bourne-Again SHell bash (GNU Bash) 5.2 Alpha |a |gnu |bash |5.2 |alpha | | | | | | | 460142|GNU Bourne-Again SHell bash (GNU Bash) 5.2 Beta |a |gnu |bash |5.2 |beta | | | | | | | 460143|GNU Bourne-Again SHell bash (GNU Bash) 5.2 Release Candidate 1|a |gnu |bash |5.2 |rc1 | | | | | | | 460144|GNU Bourne-Again SHell bash (GNU Bash) 5.2 Release Candidate 2|a |gnu |bash |5.2 |rc2 | | | | | | | 460145|GNU Bourne-Again SHell bash (GNU Bash) 5.2 Release Candidate 3|a |gnu |bash |5.2 |rc3 | | | | | | | 460146|GNU Bourne-Again SHell bash (GNU Bash) 5.2 Release Candidate 4|a |gnu |bash |5.2 |rc4 | | | | | | | ``` --- doc/stdenv/meta.chapter.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/stdenv/meta.chapter.md b/doc/stdenv/meta.chapter.md index d1823717b4b8..3eb2b5e23772 100644 --- a/doc/stdenv/meta.chapter.md +++ b/doc/stdenv/meta.chapter.md @@ -291,7 +291,7 @@ Some of them are as follows: * *vendor* - can point to the source of the package, or to Nixpkgs itself * *product* - name of the package * *version* - version of the package -* *update* - name of the latest update, can be a patch version for semantically versioned packages +* *update* - vendor-specific string part of the version string of the latest update (e.g. `rc1`, `beta`, etc...) * *edition* - deprecated and should be set to `*` You can find information about all of these attributes in the [official specification](https://csrc.nist.gov/projects/security-content-automation-protocol/specifications/cpe/naming) (heading 5.3.3, pages 11-13). @@ -301,7 +301,7 @@ Any fields that don't have a value are set to either: * `*` (ANY) when the field can match any value * `-` (NA) when the value is not meaningful or not used in the description -For example, for glibc 2.40.1 CPE would be `cpe:2.3:a:gnu:glibc:2.40:1:*:*:*:*:*:*`. +For example, for glibc 2.40.1 CPE would be `cpe:2.3:a:gnu:glibc:2.40.1:*:*:*:*:*:*:*`. #### `meta.identifiers.cpeParts` {#var-meta-identifiers-cpeParts} From a353d89292eff8f07056ed37fb948812297b432d Mon Sep 17 00:00:00 2001 From: Samuel Dionne-Riel Date: Wed, 8 Apr 2026 14:20:43 -0400 Subject: [PATCH 4/6] check-meta.nix: Stop suggesting invalid possible CPE values See the previous commit for the explanation as to why this is an invalid value. See the follow-up commits for the complete removal of the helpers. --- pkgs/stdenv/generic/check-meta.nix | 2 -- 1 file changed, 2 deletions(-) diff --git a/pkgs/stdenv/generic/check-meta.nix b/pkgs/stdenv/generic/check-meta.nix index 79f1bf5f1d09..fbf72005f92d 100644 --- a/pkgs/stdenv/generic/check-meta.nix +++ b/pkgs/stdenv/generic/check-meta.nix @@ -39,7 +39,6 @@ let inherit (lib.meta) availableOn cpeFullVersionWithVendor - tryCPEPatchVersionInUpdateWithVendor ; inherit (lib.generators) @@ -491,7 +490,6 @@ let success = true; value = cpeFullVersionWithVendor vendor version; }) - tryCPEPatchVersionInUpdateWithVendor ]; # The meta attribute is passed in the resulting attribute set, From 95584fa133c347b887a6d0c9b45e43f5b8cc79e6 Mon Sep 17 00:00:00 2001 From: Samuel Dionne-Riel Date: Wed, 8 Apr 2026 14:21:55 -0400 Subject: [PATCH 5/6] doc/meta: Drop incorrect `cpePatchVersionInUpdateWithVendor` See the previous commit for the explanation as to why this is an invalid value. See the follow-up commits for the complete removal of the helpers. --- doc/stdenv/meta.chapter.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/doc/stdenv/meta.chapter.md b/doc/stdenv/meta.chapter.md index 3eb2b5e23772..1fac5244af66 100644 --- a/doc/stdenv/meta.chapter.md +++ b/doc/stdenv/meta.chapter.md @@ -317,14 +317,13 @@ It is up to the package author to make sure all parts are correct and match expe Following functions help with filling out `version` and `update` fields: * [`lib.meta.cpeFullVersionWithVendor`](#function-library-lib.meta.cpeFullVersionWithVendor) -* [`lib.meta.cpePatchVersionInUpdateWithVendor`](#function-library-lib.meta.cpePatchVersionInUpdateWithVendor) For many packages to make CPE available it should be enough to specify only: ```nix { # ... - meta.identifiers.cpeParts = lib.meta.cpePatchVersionInUpdateWithVendor vendor version; + meta.identifiers.cpeParts = lib.meta.cpeFullVersionWithVendor vendor version; } ``` From ee0f02af4467e7e67c06b0234571c3be45bc0423 Mon Sep 17 00:00:00 2001 From: Samuel Dionne-Riel Date: Wed, 8 Apr 2026 14:23:13 -0400 Subject: [PATCH 6/6] lib.meta: Drop incorrect `cpePatchVersionInUpdateWithVendor` and `cpePatchVersionInUpdateWithVendor` See the previous commits for the explanation as to why this is an invalid value. See the follow-up commits for the complete removal of the helpers. --- lib/meta.nix | 128 --------------------------------------------------- 1 file changed, 128 deletions(-) diff --git a/lib/meta.nix b/lib/meta.nix index 1a1676f56aff..3341caf0e0fb 100644 --- a/lib/meta.nix +++ b/lib/meta.nix @@ -633,132 +633,4 @@ rec { update = "*"; }; - /** - Alternate version of [`lib.meta.cpePatchVersionInUpdateWithVendor`](#function-library-lib.meta.cpePatchVersionInUpdateWithVendor). - If `cpePatchVersionInUpdateWithVendor` succeeds, returns an attribute set with `success` set to `true` and `value` set to the result. - Otherwise, `success` is set to `false` and `error` is set to the string representation of the error. - - # Inputs - - `vendor` - - : package's vendor - - `version` - - : package's version - - # Type - - ``` - tryCPEPatchVersionInUpdateWithVendor :: String -> String -> ({ success = true; value :: { update :: String; vendor :: String; version :: String; }; } | { success = false; error :: String; }) - ``` - - # Examples - :::{.example} - ## `lib.meta.tryCPEPatchVersionInUpdateWithVendor` usage example - - ```nix - lib.meta.tryCPEPatchVersionInUpdateWithVendor "gnu" "1.2.3" - => { - success = true; - value = { - vendor = "gnu"; - version = "1.2"; - update = "3"; - }; - } - ``` - - ::: - :::{.example} - ## `lib.meta.cpePatchVersionInUpdateWithVendor` error example - - ```nix - lib.meta.tryCPEPatchVersionInUpdateWithVendor "gnu" "5.3p0" - => { - success = false; - error = "version 5.3p0 doesn't match regex `([0-9]+\\.[0-9]+)\\.([0-9]+)`"; - } - ``` - - ::: - */ - tryCPEPatchVersionInUpdateWithVendor = - vendor: version: - let - regex = "([0-9]+\\.[0-9]+)\\.([0-9]+)"; - # we have to call toString here in case version is an attrset with __toString attribute - versionMatch = builtins.match regex (toString version); - in - if versionMatch == null then - { - success = false; - error = "version ${version} doesn't match regex `${regex}`"; - } - else - { - success = true; - value = { - inherit vendor; - version = elemAt versionMatch 0; - update = elemAt versionMatch 1; - }; - }; - - /** - Generate [CPE parts](#var-meta-identifiers-cpeParts) from inputs. Copies `vendor` to the result. When `version` matches `X.Y.Z` where all parts are numerical, sets `version` and `update` fields to `X.Y` and `Z`. Throws an error if the version doesn't match the expected template. - - # Inputs - - `vendor` - - : package's vendor - - `version` - - : package's version - - # Type - - ``` - cpePatchVersionInUpdateWithVendor :: String -> String -> { update :: String; vendor :: String; version :: String; } - ``` - - # Examples - :::{.example} - ## `lib.meta.cpePatchVersionInUpdateWithVendor` usage example - - ```nix - lib.meta.cpePatchVersionInUpdateWithVendor "gnu" "1.2.3" - => { - vendor = "gnu"; - version = "1.2"; - update = "3"; - } - ``` - - ::: - :::{.example} - ## `lib.meta.cpePatchVersionInUpdateWithVendor` usage in derivations - - ```nix - mkDerivation rec { - version = "1.2.3"; - # ... - meta = { - # ... - identifiers.cpeParts = lib.meta.cpePatchVersionInUpdateWithVendor "gnu" version; - }; - } - ``` - - ::: - */ - cpePatchVersionInUpdateWithVendor = - vendor: version: - let - result = tryCPEPatchVersionInUpdateWithVendor vendor version; - in - if result.success then result.value else throw result.error; }