1212import requests
1313from bs4 import BeautifulSoup
1414from packageurl import PackageURL
15+ from univers .version_range import GenericVersionRange
16+ from univers .versions import GenericVersion
1517
1618from vulnerabilities import severity_systems
1719from vulnerabilities .importer import AdvisoryData
20+ from vulnerabilities .importer import AffectedPackage
1821from vulnerabilities .importer import Importer
1922from vulnerabilities .importer import Reference
2023from vulnerabilities .importer import VulnerabilitySeverity
21- from vulnerabilities .utils import nearest_patched_package
2224
2325
2426class PostgreSQLImporter (Importer ):
2527
2628 root_url = "https://www.postgresql.org/support/security/"
29+ license_url = "https://www.postgresql.org/about/licence/"
30+ spdx_license_expression = "PostgreSQL"
2731
28- def updated_advisories (self ):
29- advisories = []
32+ def advisory_data (self ):
3033 known_urls = {self .root_url }
3134 visited_urls = set ()
35+ data_by_url = {}
3236 while True :
3337 unvisited_urls = known_urls - visited_urls
3438 for url in unvisited_urls :
3539 data = requests .get (url ).content
36- advisories . extend ( to_advisories ( data ))
40+ data_by_url [ url ] = data
3741 visited_urls .add (url )
3842 known_urls .update (find_advisory_urls (data ))
3943
4044 if known_urls == visited_urls :
4145 break
4246
43- return self .batch_advisories (advisories )
47+ for url , data in data_by_url .items ():
48+ yield from to_advisories (data )
4449
4550
4651def to_advisories (data ):
@@ -54,29 +59,43 @@ def to_advisories(data):
5459 if "windows" in summary .lower ():
5560 pkg_qualifiers = {"os" : "windows" }
5661
57- affected_packages = [
58- PackageURL (
59- type = "generic" ,
60- name = "postgresql" ,
61- version = version .strip (),
62- qualifiers = pkg_qualifiers ,
63- )
64- for version in affected_col .text .split ("," )
65- ]
66-
67- fixed_packages = [
68- PackageURL (
69- type = "generic" ,
70- name = "postgresql" ,
71- version = version .strip (),
72- qualifiers = pkg_qualifiers ,
62+ affected_packages = []
63+ affected_version_list = affected_col .text .split ("," )
64+ fixed_version_list = fixed_col .text .split ("," )
65+
66+ if fixed_version_list :
67+ for fixed_version in fixed_version_list :
68+ affected_packages .append (
69+ AffectedPackage (
70+ package = PackageURL (
71+ name = "postgresql" ,
72+ # TODO: See https://github.com/nexB/vulnerablecode/issues/990
73+ type = "generic" ,
74+ qualifiers = pkg_qualifiers ,
75+ ),
76+ affected_version_range = GenericVersionRange .from_versions (
77+ affected_version_list
78+ )
79+ if affected_version_list
80+ else None ,
81+ fixed_version = GenericVersion (fixed_version ) if fixed_version else None ,
82+ )
83+ )
84+ elif affected_version_list :
85+ affected_packages .append (
86+ AffectedPackage (
87+ package = PackageURL (
88+ name = "postgresql" ,
89+ # TODO: See https://github.com/nexB/vulnerablecode/issues/990
90+ type = "generic" ,
91+ qualifiers = pkg_qualifiers ,
92+ ),
93+ affected_version_range = GenericVersionRange .from_versions (affected_version_list ),
94+ )
7395 )
74- for version in fixed_col .text .split ("," )
75- if version
76- ]
77-
96+ cve_id = ""
7897 try :
79- cve_id = ref_col .select ("nobr" )[0 ].text
98+ cve_id = ref_col .select (". nobr" )[0 ].text
8099 # This is for the anomaly in https://www.postgresql.org/support/security/8.1/ 's
81100 # last entry
82101 except IndexError :
@@ -102,21 +121,20 @@ def to_advisories(data):
102121 )
103122 severities .append (severity )
104123 references .append (Reference (url = link , severities = severities ))
105-
106- advisories .append (
107- AdvisoryData (
108- vulnerability_id = cve_id ,
109- summary = summary ,
110- references = references ,
111- affected_packages = nearest_patched_package (affected_packages , fixed_packages ),
124+ if cve_id :
125+ advisories .append (
126+ AdvisoryData (
127+ aliases = [cve_id ],
128+ summary = summary ,
129+ references = references ,
130+ affected_packages = affected_packages ,
131+ )
112132 )
113- )
114-
115133 return advisories
116134
117135
118136def find_advisory_urls (page_data ):
119- soup = BeautifulSoup (page_data )
137+ soup = BeautifulSoup (page_data , features = "lxml" )
120138 return {
121139 urlparse .urljoin ("https://www.postgresql.org/" , a_tag .attrs ["href" ])
122140 for a_tag in soup .select ("h3+ p a" )
0 commit comments