Skip to content

Commit 82ccffd

Browse files
hai1337PorterCoder
andauthored
docs: increase docstring coverage to 100% (#4913)
Signed-off-by: Thomas, Hailee <[email protected]> Signed-off-by: Patel, Narendra <[email protected]>> Signed-off-by: Menchaca, Jesus <[email protected]> fixes: #4900 Co-authored-by: Austin Porter <[email protected]>
1 parent 1dd0238 commit 82ccffd

11 files changed

+236
-2
lines changed

cve_bin_tool/available_fix/redhat_cve_tracker.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,16 @@
1414

1515

1616
class RedhatCVETracker:
17+
"""
18+
RedhatCVETracker is responsible for tracking CVE
19+
information for Red Hat distributions. It retrieves and parses CVE data to provide
20+
information about available fixes and affected packages.
21+
22+
Attributes:
23+
distro_name (str): The name of the distribution.
24+
distro_codename (str): The codename of the distribution.
25+
"""
26+
1727
def __init__(self, distro_name: str, distro_codename: str):
1828
self.distro_name = distro_name
1929
self.distro_codename = distro_codename

cve_bin_tool/cve_scanner.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -474,11 +474,28 @@ def metric(self, cve_number, epss_percentile, epss_probability):
474474
return met
475475

476476
def __enter__(self):
477+
"""
478+
Establishes a connection to the SQLite database and initializes the cursor.
479+
480+
Returns:
481+
CVEScanner: The instance of the CVEScanner with an active database connection.
482+
"""
477483
self.connection = sqlite3.connect(self.dbname)
478484
self.connection.row_factory = sqlite3.Row
479485
self.cursor = self.connection.cursor()
480486
return self
481487

482488
def __exit__(self, exc_type, exc_val, exc_tb):
489+
"""
490+
Closes the cursor and the SQLite database connection.
491+
492+
Args:
493+
exc_type (type): The exception type.
494+
exc_val (Exception): The exception instance.
495+
exc_tb (traceback): The traceback object.
496+
497+
Returns:
498+
None
499+
"""
483500
self.cursor.close()
484501
self.connection.close()

cve_bin_tool/data_sources/nvd_source.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,15 @@ def format_data(self, all_cve_entries):
186186
return cve_data, affects_data
187187

188188
def parse_node(self, node: dict[str, list[dict[str, str]]]) -> list[dict[str, str]]:
189+
"""
190+
Parses a node from the NVD data to extract affected vendor, product, and version information.
191+
192+
Args:
193+
node (dict): A dictionary representing a node in the NVD data.
194+
195+
Returns:
196+
list[dict]: A list of dictionaries containing vendor, product, and version information.
197+
"""
189198
affects_list = []
190199
if "cpe_match" in node:
191200
vulnerable_matches = (m for m in node["cpe_match"] if m["vulnerable"])
@@ -350,6 +359,15 @@ def format_data_api2(self, all_cve_entries):
350359
def parse_node_api2(
351360
self, node: dict[str, list[dict[str, str]]]
352361
) -> list[dict[str, str]]:
362+
"""
363+
Parses a node from the NVD API 2.0 data to extract affected vendor, product, and version information.
364+
365+
Args:
366+
node (dict): A dictionary representing a node in the NVD API 2.0 data.
367+
368+
Returns:
369+
list[dict]: A list of dictionaries containing vendor, product, and version information.
370+
"""
353371
affects_list = []
354372
if "cpeMatch" in node:
355373
vulnerable_matches = (m for m in node["cpeMatch"] if m["vulnerable"])
@@ -462,6 +480,16 @@ async def nist_fetch_using_api(self) -> list:
462480
async def getmeta(
463481
self, session: RateLimiter, meta_url: str
464482
) -> tuple[str, dict[str, str]]:
483+
"""
484+
Retrieves metadata for a given URL.
485+
486+
Args:
487+
session (RateLimiter): The session used to make HTTP requests.
488+
meta_url (str): The URL to fetch metadata from.
489+
490+
Returns:
491+
tuple: A tuple containing the URL for the JSON data and a dictionary of metadata.
492+
"""
465493
async with await session.get(meta_url) as response:
466494
response.raise_for_status()
467495
return (
@@ -476,6 +504,15 @@ async def getmeta(
476504
)
477505

478506
async def nist_scrape(self, session: RateLimiter):
507+
"""
508+
Scrapes the NVD feed page to get metadata links for CVE data.
509+
510+
Args:
511+
session (RateLimiter): The session used to make HTTP requests.
512+
513+
Returns:
514+
dict: A dictionary containing metadata links and their corresponding SHA values.
515+
"""
479516
async with await session.get(self.feed) as response:
480517
response.raise_for_status()
481518
page = await response.text()

cve_bin_tool/error_handler.py

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ class InvalidExtensionError(Exception):
138138

139139

140140
class SigningError(Exception):
141-
"""Error while signing or verifing the sign"""
141+
"""Error while signing or verifying the sign"""
142142

143143

144144
class NetworkConnectionError(Exception):
@@ -154,13 +154,32 @@ class VEXError(Exception):
154154

155155

156156
class ErrorMode(Enum):
157+
"""Defines different error handling modes.
158+
159+
Attributes:
160+
Ignore (int): Ignore errors.
161+
NoTrace (int): Do not print traceback.
162+
TruncTrace (int): Print truncated traceback.
163+
FullTrace (int): Print full traceback.
164+
"""
165+
157166
Ignore = 0
158167
NoTrace = 1
159168
TruncTrace = 2
160169
FullTrace = 3
161170

162171

163172
def excepthook(exc_type, exc_val, exc_tb):
173+
"""Custom exception hook to handle uncaught exceptions.
174+
175+
Args:
176+
exc_type (type): Exception type.
177+
exc_val (BaseException): Exception instance.
178+
exc_tb (traceback): Traceback object.
179+
180+
Returns:
181+
None
182+
"""
164183
trace = Traceback.from_exception(exc_type, exc_val, exc_tb)
165184
CONSOLE.print(trace)
166185
if isinstance(exc_val, SystemExit):
@@ -198,9 +217,24 @@ def __init__(
198217
self.exc_val = None
199218

200219
def __enter__(self):
220+
"""Enter the runtime context related to this object.
221+
222+
Returns:
223+
ErrorHandler: The error handler instance.
224+
"""
201225
return self
202226

203227
def __exit__(self, exc_type, exc_val, exc_tb):
228+
"""Exit the runtime context related to this object.
229+
230+
Args:
231+
exc_type (type): Exception type.
232+
exc_val (BaseException): Exception instance.
233+
exc_tb (traceback): Traceback object.
234+
235+
Returns:
236+
bool: True if the exception is handled, False otherwise.
237+
"""
204238
if isinstance(exc_val, SystemExit):
205239
self.exit_code = exc_val.code
206240
self.exc_val = exc_val

cve_bin_tool/extractor.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -490,13 +490,39 @@ async def __aexit__(self, exc_type, exc, exc_tb):
490490
await aio_rmdir(self.tempdir)
491491

492492
def extract(self, filename):
493+
"""
494+
Run the extractor.
495+
496+
Args:
497+
filename (str): The name of the file to extract.
498+
499+
Returns:
500+
str: The path to the extracted files.
501+
"""
493502
return run_coroutine(self.aio_extract(filename))
494503

495504
def __enter__(self):
505+
"""
506+
Create a temporary directory to extract files to.
507+
508+
Returns:
509+
TempDirExtractorContext: The current instance with a temporary directory created.
510+
"""
496511
self.tempdir = tempfile.mkdtemp(prefix="cve-bin-tool-")
497512
return self
498513

499514
def __exit__(self, exc_type, exc_val, exc_tb):
515+
"""
516+
Remove all extraction directories that need to be cleaned up.
517+
518+
Args:
519+
exc_type (type): The exception type.
520+
exc_val (Exception): The exception instance.
521+
exc_tb (traceback): The traceback object.
522+
523+
Returns:
524+
None
525+
"""
500526
with ErrorHandler(mode=self.error_mode, logger=self.logger):
501527
shutil.rmtree(self.tempdir)
502528

@@ -515,6 +541,15 @@ def __init__(self):
515541
super().__init__(mime=Lzma.MIME, extension=Lzma.EXTENSION)
516542

517543
def match(self, buf):
544+
"""
545+
Check if the buffer matches the LZMA file signature.
546+
547+
Args:
548+
buf (bytes): The buffer to check.
549+
550+
Returns:
551+
bool: True if the buffer matches the LZMA file signature, False otherwise.
552+
"""
518553
return (
519554
len(buf) > 3
520555
and buf[0] == 0x5D

cve_bin_tool/file.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,14 @@ async def aio_is_binary(filename: str) -> bool:
2828

2929

3030
def is_binary(filename: str) -> bool:
31+
"""Determine if a file is an executable binary.
32+
33+
Args:
34+
filename (str): The path to the file to check.
35+
36+
Returns:
37+
bool: True if the file is an executable binary, False otherwise.
38+
"""
3139
return run_coroutine(aio_is_binary(filename))
3240

3341

cve_bin_tool/helper_script.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,8 @@ def output_single(self) -> None:
376376
else:
377377
rprint(
378378
f'\t\t[bright_green]r"{escape_rich_console_close(filename)}"[/], <--- you could just use "{self.product_name}" to match this file'
379-
) # to single-handedly match filenames of type varnishd, varnishlog, varnishtop, etc.
379+
# to single-handedly match filenames of type varnishd, varnishlog, varnishtop, etc.
380+
)
380381
else:
381382
rprint(f'\t\t[green]r"{escape_rich_console_close(filename)}"[/],')
382383
print("\t]")
@@ -468,6 +469,15 @@ def scan_files(args) -> None:
468469

469470

470471
def main(argv=None) -> None:
472+
"""
473+
Main function to parse command-line arguments and initiate the scanning process.
474+
475+
Args:
476+
argv (list, optional): List of command-line arguments. Defaults to None.
477+
478+
Returns:
479+
None
480+
"""
471481
argv = argv or sys.argv
472482

473483
parser = argparse.ArgumentParser(

cve_bin_tool/merge.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,34 @@
3333

3434

3535
class MergeReports:
36+
"""
37+
A class to merge multiple intermediate JSON reports generated by cve-bin-tool.
38+
39+
Attributes:
40+
merge_files (list[str]): List of file paths to merge.
41+
logger (Logger | None): Logger instance for logging messages.
42+
error_mode (ErrorMode): Mode for error handling.
43+
cache_dir (str): Directory for caching intermediate files.
44+
score (int): Score threshold for filtering CVEs.
45+
filter_tag (list[str]): List of tags to filter the reports.
46+
intermediate_cve_data (list): List to store intermediate CVE data.
47+
all_cve_data (list): List to store all merged CVE data.
48+
file_stack (list): Stack to keep track of files being processed.
49+
total_inter_files (int): Total number of intermediate files processed.
50+
total_files (int): Total number of files processed.
51+
products_with_cve (int): Total number of products with CVEs.
52+
products_without_cve (int): Total number of products without CVEs.
53+
merged_files (list): List to store merged file tags.
54+
walker (DirWalk): Directory walker instance for scanning files.
55+
56+
Methods:
57+
recursive_scan(merge_files): Recursively scan all JSON files in the given paths.
58+
scan_intermediate_file(filename): Read and verify an intermediate JSON file.
59+
merge_intermediate(): Merge valid intermediate dictionaries.
60+
remove_intermediate_duplicates() -> list[dict[str, str]]: Remove duplicate CVEs from intermediate data.
61+
get_intermediate_cve_scanner(cve_data_list, score) -> list[CVEScanner]: Get CVEScanner objects from CVE data.
62+
"""
63+
3664
def __init__(
3765
self,
3866
merge_files: list[str],

cve_bin_tool/nvd_api.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,29 @@
3636

3737

3838
class NVD_API:
39+
"""
40+
A class to interact with the National Vulnerability Database (NVD) API.
41+
42+
This class provides methods to retrieve and process CVE data from the NVD.
43+
44+
Attributes:
45+
logger (Logger): Logger instance for logging messages.
46+
feed (str): URL of the NVD feed.
47+
session (aiohttp.ClientSession): HTTP session for making requests.
48+
page_size (int): Number of results per page.
49+
max_fail (int): Maximum number of allowed failures before pausing requests.
50+
interval (int): Interval in seconds between successive requests.
51+
error_mode (ErrorMode): Error handling mode.
52+
incremental_update (bool): Flag to indicate if incremental updates are enabled.
53+
api_key (str): API key for accessing the NVD API.
54+
api_version (str): Version of the NVD API.
55+
max_hosts (int): Number of simultaneous connections.
56+
total_results (int): Total number of CVE results.
57+
failed_count (int): Count of failed requests.
58+
all_cve_entries (list): List to store all CVE entries.
59+
invalid_api (bool): Flag to indicate if the API key is invalid.
60+
"""
61+
3962
def __init__(
4063
self,
4164
logger: Logger = LOGGER.getChild("NVD_API"),

cve_bin_tool/package_list_parser.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,23 @@
3030

3131

3232
class PackageListParser:
33+
"""
34+
A class to parse package lists and retrieve package information.
35+
36+
This class supports parsing package lists from various Linux distributions
37+
and Python package lists. It retrieves package information and checks for
38+
vulnerabilities using the CVE database.
39+
40+
Attributes:
41+
input_file (str): The path to the input file containing a list of packages.
42+
logger (Logger): Logger object for logging messages.
43+
error_mode (ErrorMode): Specifies how errors should be handled.
44+
parsed_data_without_vendor (Dict[Any, Any]): Parsed package data without vendor information.
45+
parsed_data_with_vendor (Dict[Any, Any]): Parsed package data with vendor information.
46+
package_names_with_vendor (List[Any]): List of package names with vendor information.
47+
package_names_without_vendor (List[Any]): List of package names without vendor information.
48+
"""
49+
3350
def __init__(
3451
self,
3552
input_file: str,

cve_bin_tool/util.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,12 +173,27 @@ def __identity_members(self):
173173
return (self.vendor, self.product, self.version)
174174

175175
def __eq__(self, other):
176+
"""
177+
Check if this ProductInfo instance is equal to another instance.
178+
179+
Args:
180+
other (ProductInfo): The other instance to compare with.
181+
182+
Returns:
183+
bool: True if both instances are equal, False otherwise.
184+
"""
176185
if type(other) is type(self):
177186
return self.__identity_members() == other.__identity_members()
178187
else:
179188
return False
180189

181190
def __hash__(self):
191+
"""
192+
Compute the hash value for this ProductInfo instance.
193+
194+
Returns:
195+
int: The hash value of the instance.
196+
"""
182197
return hash(self.__identity_members())
183198

184199

0 commit comments

Comments
 (0)