Skip to content

Commit 923197d

Browse files
committed
Refactor according to first review
Use batch_advisories for now. It has it's own problems and there's #338 for that. The generator thing won't do much, since we are importing like 10-20 MBs of data. The codebase already has overuse of methods starting with _ , I'd say avoid them. They don't help with readability nor are they trivial in this case _parse_md and _parse_yml: The name is misleading. The function is parsing + enriching the data. converted to get_advisories_from_yml and get_advisories_from_md Remove `"branch": None` in importer_yielder Group imports Signed-off-by: Hritik Vijay <hritikxx8@gmail.com>
1 parent 2a2597a commit 923197d

2 files changed

Lines changed: 26 additions & 75 deletions

File tree

vulnerabilities/importer_yielder.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,6 @@
240240
"last_run": None,
241241
"data_source": "MozillaDataSource",
242242
"data_source_cfg": {
243-
"branch": None,
244243
"repository_url": "https://github.com/mozilla/foundation-security-advisories",
245244
},
246245
},

vulnerabilities/importers/mozilla.py

Lines changed: 26 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,19 @@
1-
from typing import Set, List, Generator
2-
31
import re
4-
import asyncio
5-
from bs4 import BeautifulSoup
6-
from packageurl import PackageURL
7-
import requests
2+
from typing import List
3+
from typing import Set
84

95
import yaml
6+
from bs4 import BeautifulSoup
107
from markdown import markdown
8+
from packageurl import PackageURL
119

1210
from vulnerabilities.data_source import Advisory
1311
from vulnerabilities.data_source import GitDataSource
1412
from vulnerabilities.data_source import Reference
1513
from vulnerabilities.data_source import VulnerabilitySeverity
16-
from vulnerabilities.severity_systems import scoring_systems
17-
from vulnerabilities.package_managers import GitHubTagsAPI
1814
from vulnerabilities.helpers import is_cve
15+
from vulnerabilities.helpers import split_markdown_front_matter
16+
from vulnerabilities.severity_systems import scoring_systems
1917

2018

2119
REPOSITORY = "mozilla/foundation-security-advisories"
@@ -31,61 +29,40 @@ def __enter__(self):
3129
recursive=True, subdir="announce"
3230
)
3331

34-
# Do we need this ?
35-
# self.version_api = GitHubTagsAPI()
36-
# self.set_api()
37-
38-
def set_api(self):
39-
repository = "/".join(self.config.repository_url.split("/")[-2:])
40-
asyncio.run(self.version_api.load_api([repository]))
41-
42-
def added_advisories(self) -> Set[Advisory]:
43-
return self._load_advisories(self._added_files)
44-
4532
def updated_advisories(self) -> Set[Advisory]:
46-
return self._load_advisories(self._updated_files)
47-
48-
def _load_advisories(self, files) -> Set[Advisory]:
49-
"""
50-
Yields list of advisories of batch size
51-
"""
33+
files = self._updated_files.union(self._added_files)
5234
files = [
5335
f for f in files if f.endswith(".md") or f.endswith(".yml")
5436
] # skip irrelevant files
5537

5638
advisories = []
5739
for path in files:
58-
for advisory in self._to_advisories(path):
59-
advisories.append(advisory)
60-
if len(advisories) >= self.batch_size:
61-
yield advisories
62-
advisories = []
40+
advisories.extend(self.to_advisories(path))
6341

64-
# In case batch size is too high
65-
yield advisories
42+
return self.batch_advisories(advisories)
6643

67-
def _to_advisories(self, path: str) -> List[Advisory]:
44+
def to_advisories(self, path: str) -> List[Advisory]:
6845
"""
6946
Convert a file to corresponding advisories.
7047
This calls proper method to handle yml/md files.
7148
"""
72-
mfsa_id = self._mfsa_id_from_filename(path)
49+
mfsa_id = self.mfsa_id_from_filename(path)
7350

7451
with open(path) as lines:
7552
if path.endswith(".md"):
76-
return self._parse_md(mfsa_id, lines)
77-
elif path.endswith(".yml"):
78-
return self._parse_yml(mfsa_id, lines)
53+
return self.get_advisories_from_md(mfsa_id, lines)
54+
if path.endswith(".yml"):
55+
return self.get_advisories_from_yml(mfsa_id, lines)
7956

8057
return []
8158

82-
def _parse_yml(self, mfsa_id, lines) -> List[Advisory]:
59+
def get_advisories_from_yml(self, mfsa_id, lines) -> List[Advisory]:
8360
advisories = []
8461
data = yaml.safe_load(lines)
8562
data["mfsa_id"] = mfsa_id
8663

87-
fixed_package_urls = self._get_package_urls(data.get("fixed_in"))
88-
references = self._get_references(data)
64+
fixed_package_urls = self.get_package_urls(data.get("fixed_in"))
65+
references = self.get_references(data)
8966

9067
if not data.get("advisories"):
9168
return []
@@ -103,16 +80,15 @@ def _parse_yml(self, mfsa_id, lines) -> List[Advisory]:
10380

10481
return advisories
10582

106-
def _parse_md(self, mfsa_id, lines) -> List[Advisory]:
107-
yamltext, mdtext = self._parse_md_front_matter(lines)
108-
83+
def get_advisories_from_md(self, mfsa_id, lines) -> List[Advisory]:
84+
yamltext, mdtext = split_markdown_front_matter(lines)
10985
data = yaml.safe_load(yamltext)
11086
data["mfsa_id"] = mfsa_id
11187

112-
fixed_package_urls = self._get_package_urls(data.get("fixed_in"))
113-
references = self._get_references(data)
88+
fixed_package_urls = self.get_package_urls(data.get("fixed_in"))
89+
references = self.get_references(data)
11490

115-
description = self._html_get_p_under_h3(markdown(mdtext), "description")
91+
description = self.html_get_p_under_h3(markdown(mdtext), "description")
11692

11793
# FIXME: add references from md ? They lack a proper reference id and are mostly bug reports
11894

@@ -126,7 +102,7 @@ def _parse_md(self, mfsa_id, lines) -> List[Advisory]:
126102
)
127103
]
128104

129-
def _html_get_p_under_h3(self, html, h3: str):
105+
def html_get_p_under_h3(self, html, h3: str):
130106
soup = BeautifulSoup(html, features="lxml")
131107
h3tag = soup.find("h3", text=lambda txt: txt.lower() == h3)
132108
p = ""
@@ -138,38 +114,14 @@ def _html_get_p_under_h3(self, html, h3: str):
138114
p += tag.get_text()
139115
return p
140116

141-
def _parse_md_front_matter(self, lines):
142-
"""
143-
Return the YAML and MD sections.
144-
:param: lines iterator
145-
:return: str YAML, str Markdown
146-
"""
147-
# fm_count: 0: init, 1: in YAML, 2: in Markdown
148-
fm_count = 0
149-
yaml_lines = []
150-
md_lines = []
151-
for line in lines:
152-
# first line we care about is FM start
153-
if fm_count < 2 and line.strip() == "---":
154-
fm_count += 1
155-
continue
156-
157-
if fm_count == 1:
158-
yaml_lines.append(line)
159-
160-
if fm_count == 2:
161-
md_lines.append(line)
162-
163-
return "".join(yaml_lines), "".join(md_lines)
164-
165-
def _mfsa_id_from_filename(self, filename):
117+
def mfsa_id_from_filename(self, filename):
166118
match = MFSA_FILENAME_RE.search(filename)
167119
if match:
168120
return "mfsa" + match.group(1)
169121

170122
return None
171123

172-
def _get_package_urls(self, pkgs: List[str]) -> List[PackageURL]:
124+
def get_package_urls(self, pkgs: List[str]) -> List[PackageURL]:
173125
package_urls = [
174126
PackageURL(
175127
type="mozilla",
@@ -182,7 +134,7 @@ def _get_package_urls(self, pkgs: List[str]) -> List[PackageURL]:
182134
]
183135
return package_urls
184136

185-
def _get_references(self, data: any) -> List[Reference]:
137+
def get_references(self, data: any) -> List[Reference]:
186138
"""
187139
Returns a list of references
188140
Currently only considers the given mfsa as a reference

0 commit comments

Comments
 (0)