Skip to content

Commit

Permalink
feat: added PURL generation to rust parser (#3859)
Browse files Browse the repository at this point in the history
* Related: #3771

Signed-off-by: Meet Soni <meetsoni3017@gmail.com>
  • Loading branch information
inosmeet committed Apr 3, 2024
1 parent b5f7e01 commit dc95e61
Showing 1 changed file with 48 additions and 4 deletions.
52 changes: 48 additions & 4 deletions cve_bin_tool/parsers/rust.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,61 @@
# Copyright (C) 2022 Intel Corporation
# SPDX-License-Identifier: GPL-3.0-or-later

import re

from cve_bin_tool.parsers import Parser


class RustParser(Parser):
"""
Parser implementation for Rust dependency files (Cargo.toml).
This parser is designed to parse Rust dependency files (Cargo.toml) and generate
Package URL (PURL) strings based on the packages and their versions listed in the file.
Attributes:
cve_db (CVEDB): The CVE database instance used for vulnerability information.
logger (Logger): The logger instance for logging messages and debugging information.
Methods:
generate_purl(product, version, vendor):
Generates PURL after normalizing all components.
run_checker(filename):
Parse the Rust dependency file and yield valid PURLs for the packages listed in the file.
"""

def __init__(self, cve_db, logger):
super().__init__(cve_db, logger)
self.purl_pkg_type = "cargo"

def generate_purl(self, product, version, vendor, qualifier={}, subpath=None):
"""Generates PURL after normalizing all components."""

product = re.sub(r"^[^a-zA-Z_]|[^a-zA-Z0-9_-]", "", product)
vendor = re.sub(r"^[^a-zA-Z_]|[^a-zA-Z0-9_-]", "", vendor)
version = re.sub(r"^[^0-9]|[^a-zA-Z0-9.+-]", "", version)

if not re.match(r"^[a-zA-Z_]|[a-zA-Z0-9_-]", product):
return
if vendor == "":
vendor = "UNKNOWN"
if version == "":
version = "UNKNOWN"

purl = super().generate_purl(
product,
version,
vendor,
qualifier,
subpath,
)

return purl

def run_checker(self, filename):
"""Parse the file and yield valid PURLs."""
self.filename = filename
with open(filename) as fh:
# parse the multiline name and version format
lines = fh.readlines()
product = ""
version = ""
Expand All @@ -23,9 +67,9 @@ def run_checker(self, filename):
else:
if product == "" and version == "":
continue
vendor = self.find_vendor(product, version)
vendors = self.find_vendor(product, version)
if vendors is not None:
yield from vendors
product = ""
version = ""
if vendor is not None:
yield from vendor
self.logger.debug(f"Done scanning file: {self.filename}")

0 comments on commit dc95e61

Please sign in to comment.