Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: helper_script: try without lib prefix. update name detect #2962

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 60 additions & 32 deletions cve_bin_tool/helper_script.py
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,18 @@ def search_version_string(self, matched_list: list[str]) -> list[str]:
) # TODO: regex highlight in these matched strings?
return version_strings

def remove_digits(self, product_name: str) -> str:
"""
tries to remove digits from product name
Example: testpkg1.2-3.4 becomes testpkg
"""
# try removing numeric characters from the product_name
LOGGER.debug(f"removing digits from product_name={product_name}")
result = "".join(filter(lambda x: not x.isdigit(), product_name))

# skip trailing characters that can often happen after digits removal
return result.rstrip("-_. ")

def parse_filename(self, filename: str) -> tuple[str, str]:
"""
returns package_name/product_name from package_filename of types .rpm, .deb, etc.
Expand All @@ -226,7 +238,7 @@ def parse_filename(self, filename: str) -> tuple[str, str]:
product_name = filename.rsplit("-", 3)[0]
version_number = filename.rsplit("-", 3)[1]
# example: libarchive-3.5.1-1-aarch64.pkg.tar.xz
elif filename.endswith(".deb") or filename.endswith(".ipk"):
elif "_" in filename:
product_name = filename.rsplit("_")[0]
version_number = filename.rsplit("_")[1].rsplit("-")[0].rsplit("+")[0]
# example: varnish_6.4.0-3_amd64.deb
Expand All @@ -240,22 +252,57 @@ def parse_filename(self, filename: str) -> tuple[str, str]:
if not self.version_number:
self.version_number = version_number

self.vendor_product = self.find_vendor_product()

LOGGER.debug(
f"Parsing file '{filename}': Results: product_name='{self.product_name}', version_number='{self.version_number}'"
)
return product_name, version_number

# first try
self.vendor_product = self.find_vendor_product(self.product_name)
if self.vendor_product:
return product_name, version_number
# failed, check lib prefix
if self.product_name.startswith("lib"):
# try without lib prefix
LOGGER.debug(f"trying without lib in product_name={self.product_name}")
name_no_lib = self.product_name[3:]
self.vendor_product = self.find_vendor_product(name_no_lib)
if self.vendor_product:
return product_name, version_number
# try without lib prefix and digits
if any(char.isdigit() for char in name_no_lib):
self.vendor_product = self.find_vendor_product(
self.remove_digits(name_no_lib)
)
if self.vendor_product:
return product_name, version_number
# try without numeric characters
if any(char.isdigit() for char in self.product_name):
self.vendor_product = self.find_vendor_product(
self.remove_digits(self.product_name)
)
if self.vendor_product:
return product_name, version_number
# all attempts failed, raise error and ask for product_name
LOGGER.warning(
textwrap.dedent(
f"""
=================================================================
No match was found for "{self.product_name}" in database.
Please check your file or try specifying the "product_name" also.
=================================================================
"""
)
)
else:
# raise error for unknown archive types
with ErrorHandler(mode=ErrorMode.NoTrace, logger=LOGGER):
raise UnknownArchiveType(filename)

def find_vendor_product(self) -> list[tuple[str, str]]:
def find_vendor_product(self, product_name) -> list[tuple[str, str]]:
"""find vendor-product pairs from database"""

LOGGER.debug(
f"checking for product_name='{self.product_name}' and version_name='{self.version_number}' in the database"
f"checking for product_name='{product_name}' and version_name='{self.version_number}' in the database"
)

cursor = CVEDB.db_open_and_get_cursor(self)
Expand All @@ -268,7 +315,7 @@ def find_vendor_product(self) -> list[tuple[str, str]]:
if cursor is None:
return []

cursor.execute(query, {"product": self.product_name})
cursor.execute(query, {"product": product_name})
data = cursor.fetchall()

# checking if (vendor, product) was found in the database
Expand All @@ -280,41 +327,22 @@ def find_vendor_product(self) -> list[tuple[str, str]]:
textwrap.dedent(
f"""
===============================================================
Multiple ("vendor", "product") pairs found for "{self.product_name}"
Multiple ("vendor", "product") pairs found for "{product_name}"
Please manually select the appropriate pair.
===============================================================
"""
)
)
WARNED = True # prevent same warning multiple times

# we found correct product_name, set it
self.product_name = product_name
return data # [('vendor', 'product')]
else:
if self.product_name:
# removing numeric characters from the product_name
if any(char.isdigit() for char in self.product_name):
LOGGER.debug(
f"removing digits from product_name={self.product_name}"
)
self.product_name = "".join(
filter(lambda x: not x.isdigit(), self.product_name)
)
return self.find_vendor_product()
else:
# raise error and ask for product_name
LOGGER.warning(
textwrap.dedent(
f"""
=================================================================
No match was found for "{self.product_name}" in database.
Please check your file or try specifying the "product_name" also.
=================================================================
"""
)
)
return []

CVEDB.db_close(self) # type: ignore

return []

def output_single(self) -> None:
"""display beautiful output for Helper-Script"""

Expand Down
Loading