Description
In SBOM generation, encountered the following crash
╭───────────────────────────────────────────────╮
│ Products with No Identified Vulnerabilities │
╰───────────────────────────────────────────────╯
╭─────────────────────────────── Traceback (most recent call last) ────────────────────────────────╮
│ /usr/local/bin/cve-bin-tool:8 in │
│ │
│ 5 from cve_bin_tool.cli import main │
│ 6 if name == 'main': │
│ 7 │ sys.argv[0] = re.sub(r'(-script.pyw|.exe)?$', '', sys.argv[0]) │
│ ❱ 8 │ sys.exit(main()) │
│ 9 │
│ │
│.local/lib/python3.10/site-packages/cve_bin_tool/cli.py:1251 in main │
│ │
│ 1248 │ │ ) │
│ 1249 │ │ │
│ 1250 │ │ if not args["quiet"]: │
│ ❱ 1251 │ │ │ output.output_file_wrapper(output_formats) │
│ 1252 │ │ │ if args["backport_fix"] or args["available_fix"]: │
│ 1253 │ │ │ │ distro_info = args["backport_fix"] or args["available_fix"] │
│ 1254 │ │ │ │ is_backport = True if args["backport_fix"] else False │
│ │
│.local/lib/python3.10/site-packages/cve_bin_tool/output_engine/init.py:8 │
│ 24 in output_file_wrapper │
│ │
│ 821 │ def output_file_wrapper(self, output_types=["console"]): │
│ 822 │ │ """Call output_file method for all output types.""" │
│ 823 │ │ for output_type in output_types: │
│ ❱ 824 │ │ │ self.output_file(output_type) │
│ 825 │ │
│ 826 │ def output_file(self, output_type="console"): │
│ 827 │ │ """Generate a file for list of CVE""" │
│ │
│.local/lib/python3.10/site-packages/cve_bin_tool/output_engine/init.py:8 │
│ 48 in output_file │
│ │
│ 845 │ │ │ if self.filename: │
│ 846 │ │ │ │ self.filename = add_extension_if_not(self.filename, "txt") │
│ 847 │ │ │ │ self.logger.info(f"Console output stored at {self.filename}") │
│ ❱ 848 │ │ │ self.output_cves(self.filename, output_type) │
│ 849 │ │ │ return │
│ 850 │ │ │
│ 851 │ │ # Abort processing if no data to write to file and no_zero_cve_report is True │
│ │
│ .local/lib/python3.10/site-packages/cve_bin_tool/output_engine/init.py:7 │
│ 72 in output_cves │
│ │
│ 769 │ │ │ │ self.affected_versions, │
│ 770 │ │ │ ) │
│ 771 │ │ else: # console, or anything else that is unrecognised │
│ ❱ 772 │ │ │ output_console( │
│ 773 │ │ │ │ self.all_cve_data, │
│ 774 │ │ │ │ self.all_cve_version_info, │
│ 775 │ │ │ │ self.time_of_last_update, │
│ │
│ .local/lib/python3.10/site-packages/cve_bin_tool/output_engine/console.py:44 │
│ in output_console │
│ │
│ 41 │ │ │ ls_args.append(console) │
│ 42 │ │ │ _output_console_nowrap(*ls_args) │
│ 43 │ else: │
│ ❱ 44 │ │ _output_console_nowrap(*ls_args) │
│ 45 │
│ 46 │
│ 47 def _output_console_nowrap( │
│ │
│.local/lib/python3.10/site-packages/cve_bin_tool/output_engine/console.py:33 │
│ 9 in _output_console_nowrap │
│ │
│ 336 │ │ │ │ cells = [ │
│ 337 │ │ │ │ │ Text.styled(product_data.vendor, color), │
│ 338 │ │ │ │ │ Text.styled(product_data.product, color), │
│ ❱ 339 │ │ │ │ │ Text.styled(product_data.version, color), │
│ 340 │ │ │ │ ] │
│ 341 │ │ │ │ table.add_row(*cells) │
│ 342 │ │ # Print the table to the console │
│ │
│ /home/nijames-local/.local/lib/python3.10/site-packages/rich/text.py:352 in styled │
│ │
│ 349 │ │ Returns: │
│ 350 │ │ │ Text: A text instance with a style applied to the entire string. │
│ 351 │ │ """ │
│ ❱ 352 │ │ styled_text = cls(text, justify=justify, overflow=overflow) │
│ 353 │ │ styled_text.stylize(style) │
│ 354 │ │ return styled_text │
│ 355 │
│ │
│.local/lib/python3.10/site-packages/rich/text.py:156 in init │
│ │
│ 153 │ │ tab_size: Optional[int] = None, │
│ 154 │ │ spans: Optional[List[Span]] = None, │
│ 155 │ ) -> None: │
│ ❱ 156 │ │ sanitized_text = strip_control_codes(text) │
│ 157 │ │ self._text = [sanitized_text] │
│ 158 │ │ self.style = style │
│ 159 │ │ self.justify: Optional["JustifyMethod"] = justify │
│ │
│.local/lib/python3.10/site-packages/rich/control.py:198 in │
│ strip_control_codes │
│ │
│ 195 │ Returns: │
│ 196 │ │ str: String with control codes removed. │
│ 197 │ """ │
│ ❱ 198 │ return text.translate(_translate_table) │
│ 199 │
│ 200 │
│ 201 def escape_control_codes( │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
AttributeError: 'NoneType' object has no attribute 'translate'
To reproduce
Steps to reproduce the behaviour:
- scan a large package using default SBOM command
- Not sure if 100% reproducable
Expected behaviour: successfully generate SBOM
Actual behaviour: crashed before finish
Version/platform info
Version of CVE-bin-tool 3.4 (latest)
Installed from github
Operating system: Ubuntu 22.04.5 LTS
Python version (e.g. python3 --version): 3.10.12
Running in any particular CI environment we should know about? No
Anything else?
Added the following changes in python3.10/site-packages/rich/control.py to temporarily bypass the crash. Not sure if this is the true fix. I am happy to be a contributor.
def strip_control_codes(
text: str, _translate_table: Dict[int, None] = _CONTROL_STRIP_TRANSLATE
) -> str:
"""Remove control codes from text.
Args:
text (str): A string possibly contain control codes.
Returns:
str: String with control codes removed.
"""
### change begins ###
if text is not None:
return text.translate(_translate_table)
else:
return ""
### change ends ###
Hi,
Thanks for this bug report.
Patching rich/control.py will indeed bypass the crash but it seems that the root cause is that product_data.version is set to None:
.local/lib/python3.10/site-packages/cve_bin_tool/output_engine/console.py:33 │
│ 9 in _output_console_nowrap │
│ │
│ 336 │ │ │ │ cells = [ │
│ 337 │ │ │ │ │ Text.styled(product_data.vendor, color), │
│ 338 │ │ │ │ │ Text.styled(product_data.product, color), │
│ ❱ 339 │ │ │ │ │ Text.styled(product_data.version, color), │
│ 340 │ │ │ │ ] │
│ 341 │ │ │ │ table.add_row(*cells) │
│ 342 │ │ # Print the table to the console │
This should not happen.
Can you reproduce the issue with latest code (i.e. from main)? Indeed, version 3.4 has been released 10 months ago so perhaps the issue is already fixed.
If the issue is not fixed, can you spot a package with an empty version inside the SBOM generated with your bypass?
Can you provide a copy of the command line you used? And if an SBOM is provided, can you also provide this? As @ffontaine identifies, it looks like you have a package wth no version specified. Can you check that all the packages have a version (this is a required element according to the minimum SBOM standards)?