On Mon, Mar 9, 2026 at 7:29 AM <[email protected]> wrote:
>
> From: Stefano Tondo <[email protected]>
>
> CPE 2.3 formatted string binding (cpe:2.3:...) requires
> backslash escaping for special meta-characters per NISTIR 7695.
> Characters like '++' and ':' in product names must be escaped.
>
> The CPE 2.3 specification defines two bindings:
> - URI binding (cpe:/...) uses percent-encoding
> - Formatted string (cpe:2.3:...) uses backslash escaping
>
> Escape the required meta-characters with backslash:
> - Backslash (\) -> \\
> - Question mark (?) -> \?
> - Asterisk (*) -> \*
> - Colon (:) -> \:
> - Plus (+) -> \+
>
> All other characters are kept as-is without encoding.
>
> Example CPE identifiers:
> - cpe:2.3:*:*:crow:1.0\+x:*:*:*:*:*:*:*
> - cpe:2.3:*:*:sdbus-c\+\+:2.2.1:*:*:*:*:*:*:*
>
> Signed-off-by: Stefano Tondo <[email protected]>

LGTM

Reviewed-by: Joshua Watt <[email protected]>

Note: This can be merged without needing to wait for the preceding
changes in this patch series

> ---
>  meta/lib/oe/cve_check.py | 38 +++++++++++++++++++++++++++++++++++++-
>  1 file changed, 37 insertions(+), 1 deletion(-)
>
> diff --git a/meta/lib/oe/cve_check.py b/meta/lib/oe/cve_check.py
> index ae194f27cf..6555743514 100644
> --- a/meta/lib/oe/cve_check.py
> +++ b/meta/lib/oe/cve_check.py
> @@ -205,6 +205,35 @@ def get_patched_cves(d):
>      return patched_cves
>
>
> +def cpe_escape(value):
> +    r"""
> +    Escape special characters for CPE 2.3 formatted string binding.
> +
> +    CPE 2.3 formatted string binding (cpe:2.3:...) uses backslash escaping
> +    for special meta-characters, NOT percent-encoding. Percent-encoding is
> +    only used in the URI binding (cpe:/...).
> +
> +    According to NISTIR 7695, these characters need escaping:
> +    - Backslash (\) -> \\
> +    - Question mark (?) -> \?
> +    - Asterisk (*) -> \*
> +    - Colon (:) -> \:
> +    - Plus (+) -> \+ (required by some SBOM validators)
> +    """
> +    if not value:
> +        return value
> +
> +    # Escape special meta-characters for CPE 2.3 formatted string binding
> +    # Order matters: escape backslash first to avoid double-escaping
> +    result = value.replace('\\', '\\\\')
> +    result = result.replace('?', '\\?')
> +    result = result.replace('*', '\\*')
> +    result = result.replace(':', '\\:')
> +    result = result.replace('+', '\\+')
> +
> +    return result
> +
> +
>  def get_cpe_ids(cve_product, version):
>      """
>      Get list of CPE identifiers for the given product and version
> @@ -221,7 +250,14 @@ def get_cpe_ids(cve_product, version):
>          else:
>              vendor = "*"
>
> -        cpe_id = 'cpe:2.3:*:{}:{}:{}:*:*:*:*:*:*:*'.format(vendor, product, 
> version)
> +        # Encode special characters per CPE 2.3 specification
> +        encoded_vendor = cpe_escape(vendor) if vendor != "*" else vendor
> +        encoded_product = cpe_escape(product)
> +        encoded_version = cpe_escape(version)
> +
> +        cpe_id = 'cpe:2.3:*:{}:{}:{}:*:*:*:*:*:*:*'.format(
> +            encoded_vendor, encoded_product, encoded_version
> +        )
>          cpe_ids.append(cpe_id)
>
>      return cpe_ids
> --
> 2.53.0
>
-=-=-=-=-=-=-=-=-=-=-=-
Links: You receive all messages sent to this group.
View/Reply Online (#232912): 
https://lists.openembedded.org/g/openembedded-core/message/232912
Mute This Topic: https://lists.openembedded.org/mt/118221143/21656
Group Owner: [email protected]
Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub 
[[email protected]]
-=-=-=-=-=-=-=-=-=-=-=-

Reply via email to