Skip to content

Commit

Permalink
feat: helper_script: try without lib prefix. update name detect
Browse files Browse the repository at this point in the history
* fixes #2918

Signed-off-by: Przemyslaw Romaniak <[email protected]>
Signed-off-by: Bartlomiej Cieszkowski <[email protected]>
  • Loading branch information
l0ud authored and bcieszko committed May 18, 2023
1 parent 92d27dc commit 42f2f0c
Showing 1 changed file with 60 additions and 32 deletions.
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

0 comments on commit 42f2f0c

Please sign in to comment.