@@ -21,8 +21,6 @@ def __enter__(self):
2121 self ._added_files , self ._updated_files = self .file_changes (
2222 recursive = True , file_ext = 'yml' , subdir = './gems' )
2323
24- self .pkg_manager_api = rubyAPI ()
25-
2624 def updated_advisories (self ) -> Set [Advisory ]:
2725 files = self ._updated_files .union (self ._added_files )
2826 advisories = []
@@ -32,8 +30,6 @@ def updated_advisories(self) -> Set[Advisory]:
3230 return self .batch_advisories (advisories )
3331
3432 def _process_file (self , path ) -> List [Advisory ]:
35- advisories = []
36-
3733 with open (path ) as f :
3834 record = yaml .safe_load (f )
3935 package_name = record .get (
@@ -47,24 +43,20 @@ def _process_file(self, path) -> List[Advisory]:
4743 else :
4844 return
4945
50- patched_version_ranges = record .get ('patched_versions' , [])
51- # this case happens when the advisory contain 'patched_versions' field
52- # and it has value None(i.e it is empty :( )
53- if not patched_version_ranges :
54- return
55- affected_versions = self .pkg_manager_api .get_all_version_of_package (
46+ safe_version_ranges = record .get ('patched_versions' , [])
47+ # this case happens when the advisory contain only 'patched_versions' field
48+ # and it has value None(i.e it is empty :( ).
49+ if not safe_version_ranges :
50+ safe_version_ranges = []
51+ safe_version_ranges += record .get ('unaffected_versions' , [])
52+ safe_version_ranges = [i for i in safe_version_ranges if i ]
53+
54+ if not getattr (self , 'pkg_manager_api' , None ):
55+ self .pkg_manager_api = rubyAPI ()
56+ all_vers = self .pkg_manager_api .get_all_version_of_package (
5657 package_name )
57- patched_versions = set ()
58- for version_range in patched_version_ranges :
59- try :
60- spec = RangeSpecifier (version_range )
61- patched_versions .update (
62- set (filter (lambda x : x in spec , affected_versions )))
63- affected_versions -= patched_versions
64- if not affected_versions :
65- break
66- except InvalidSpecifier :
67- continue
58+ safe_versions , affected_versions = self .categorize_versions (
59+ all_vers , safe_version_ranges )
6860
6961 impacted_purls = {
7062 PackageURL (
@@ -78,7 +70,7 @@ def _process_file(self, path) -> List[Advisory]:
7870 name = package_name ,
7971 type = 'gem' ,
8072 version = version ,
81- ) for version in patched_versions }
73+ ) for version in safe_versions }
8274
8375 return Advisory (
8476 summary = record .get ('description' , '' ),
@@ -87,7 +79,26 @@ def _process_file(self, path) -> List[Advisory]:
8779 reference_urls = record .get ('url' , '' ),
8880 cve_id = cve_id
8981 )
90- return advisories
82+
83+ @staticmethod
84+ def categorize_versions (all_versions , unaffected_version_ranges ):
85+
86+ for id , elem in enumerate (unaffected_version_ranges ):
87+ try :
88+ unaffected_version_ranges [id ] = RangeSpecifier (
89+ elem .replace (' ' , '' ))
90+ except InvalidSpecifier :
91+ continue
92+
93+ safe_versions = set ()
94+ for i in all_versions :
95+ for ver_rng in unaffected_version_ranges :
96+
97+ if i in ver_rng :
98+
99+ safe_versions .add (i )
100+
101+ return (safe_versions , all_versions - safe_versions )
91102
92103
93104class rubyAPI :
0 commit comments