11# Copyright (C) 2021 Intel Corporation
22# SPDX-License-Identifier: GPL-3.0-or-later
33
4- from __future__ import annotations
5-
64import textwrap
75from collections import defaultdict
86from datetime import datetime
9- from typing import Any , DefaultDict
7+ from typing import Any , DefaultDict , Dict
108
119from rich .console import Console
1210from rich .markdown import Markdown
2018from ..theme import cve_theme
2119from ..util import ProductInfo , VersionInfo
2220from ..version import VERSION
23- from .util import get_cve_summary
21+ from .util import format_path , get_cve_summary
2422
2523
2624def format_version_range (version_info : VersionInfo ) -> str :
@@ -80,9 +78,9 @@ def output_console(*args: Any):
8078
8179
8280def _output_console_nowrap (
83- all_cve_data : dict [ProductInfo , CVEData ],
84- all_cve_version_info : dict [str , VersionInfo ],
85- time_of_last_update : datetime | str ,
81+ all_cve_data : Dict [ProductInfo , CVEData ],
82+ all_cve_version_info : Dict [str , VersionInfo ],
83+ time_of_last_update : datetime ,
8684 affected_versions : int ,
8785 exploits : bool = False ,
8886 console : Console = Console (theme = cve_theme ),
@@ -138,7 +136,8 @@ def _output_console_nowrap(
138136 console .print (table )
139137
140138 cve_by_remarks : DefaultDict [Remarks , list [dict [str , str ]]] = defaultdict (list )
141- # group cve_data by its remarks
139+ cve_by_paths : DefaultDict [Remarks , list [dict [str , str ]]] = defaultdict (list )
140+ # group cve_data by its remarks and separately by paths
142141 for product_info , cve_data in all_cve_data .items ():
143142 for cve in cve_data ["cves" ]:
144143 cve_by_remarks [cve .remarks ].append (
@@ -152,6 +151,16 @@ def _output_console_nowrap(
152151 "cvss_version" : cve .cvss_version ,
153152 }
154153 )
154+ path_elements = ", " .join (cve_data ["paths" ])
155+ for path_element in path_elements .split ("," ):
156+ path_entry = {
157+ "vendor" : product_info .vendor ,
158+ "product" : product_info .product ,
159+ "version" : product_info .version ,
160+ "paths" : path_element ,
161+ }
162+ if path_entry not in cve_by_paths [cve .remarks ]:
163+ cve_by_paths [cve .remarks ].append (path_entry )
155164 if affected_versions != 0 :
156165 try :
157166 version_info = all_cve_version_info [cve .cve_number ]
@@ -203,3 +212,32 @@ def _output_console_nowrap(
203212 if "*" in cve_data ["vendor" ]:
204213 console .print ("* vendors guessed by the tool" )
205214 break
215+
216+ # Show table of vulnerable products mapped to filename paths
217+ for remarks in sorted (cve_by_paths ):
218+ color = "yellow"
219+ console .print (
220+ Panel (f"[{ color } ] { remarks .name } CVEs [/{ color } ]" , expand = False )
221+ )
222+ # Table instance
223+ table = Table ()
224+
225+ # Add Head Columns to the Table
226+ table .add_column ("Vendor" )
227+ table .add_column ("Product" )
228+ table .add_column ("Version" )
229+ table .add_column ("Root" )
230+ table .add_column ("Filename" )
231+ color = "green"
232+ for cve_data in cve_by_paths [remarks ]:
233+ path_root = format_path (cve_data ["paths" ])
234+ cells = [
235+ Text .styled (cve_data ["vendor" ], color ),
236+ Text .styled (cve_data ["product" ], color ),
237+ Text .styled (cve_data ["version" ], color ),
238+ Text .styled (path_root [0 ], color ),
239+ Text .styled (path_root [1 ], color ),
240+ ]
241+ table .add_row (* cells )
242+ # Print the table to the console
243+ console .print (table )
0 commit comments