Merge ~eslerm/ubuntu-cve-tracker:check-cves-f-strings into ubuntu-cve-tracker:master

Proposed by Mark Esler
Status: Merged
Merged at revision: 6f6eb4c1ef0abf924ca1755f68da9bfb3b5aa8cf
Proposed branch: ~eslerm/ubuntu-cve-tracker:check-cves-f-strings
Merge into: ubuntu-cve-tracker:master
Diff against target: 701 lines (+123/-117)
1 file modified
scripts/check-cves (+123/-117)
Reviewer Review Type Date Requested Status
Steve Beattie Approve
Marc Deslauriers Approve
Review via email: mp+462539@code.launchpad.net

Commit message

check-cves: switch formatting regular strings to f-strings and friends

Description of the change

Converts formatting of regular strings to f-strings.

> F-strings provide a concise, readable way to include the value of Python expressions inside strings.
https://peps.python.org/pep-0498/

f-strings were introduced in 3.6. This means that f-strings work on bionic++.

There are four remaining cases involving regex that I did not want to change and test in this MR.

There are several cases where `print("%s" % foo)` is replaced as `print(foo)`.

And a case where concatenating strings was clearer. e.g., `str_a + str_b`

Note that f-strings cannot contain backslashes, hence cases like `print(" %s" % "\n ".join(info))` are kept.

This is my second time linting check-cves to use f-strings. I reviewed my code several times for errors after my final commit and ran several use cases.

To post a comment you must log in.
Revision history for this message
Marc Deslauriers (mdeslaur) wrote :

These changes LGTM. Thanks for breaking down all your refactoring into reviewable changes!

review: Approve
Revision history for this message
Steve Beattie (sbeattie) wrote :

 review approve

On Fri, Mar 15, 2024 at 10:52:17PM -0000, Mark Esler wrote:
> @@ -1344,20 +1351,20 @@ class CVEHandler(xml.sax.handler.ContentHandler):
> if dpkg_compare_versions(version, 'ge', fixed_version):
> if rel == cve_lib.devel_release:
> rel = 'devel'
> - fixed_in += ",%s,%s" % (rel, version)
> + fixed_in += f",{rel},{version}"
> break
> elif self.debian[cve]['pkgs'][pkg]['state'].startswith('<not-affected>') and \
> len(self.debian[cve]['pkgs'][pkg]['priority']) > 0:
> # capture that debian believes their version is unaffected
> - not_affected.append((pkg, "debian: %s" % self.debian[cve]['pkgs'][pkg]['priority']))
> - cmd += ['-p', "%s%s" % (pkg, fixed_in)]
> + not_affected.append(pkg, f"debian: {self.debian[cve]['pkgs'][pkg]['priority']}")

Note that the append() call here gets converted from a tuple to two
arguments, which append() won't accept. I added a commit to reinstate
the tuple:

 https://git.launchpad.net/ubuntu-cve-tracker/commit/?id=946c26c48f8619120efe31c73581823d082dbb42

and have merged your changes with it to master.

Thanks!

--
Steve Beattie
<email address hidden>

review: Approve
Revision history for this message
Marc Deslauriers (mdeslaur) wrote :

Oh, nice catch, I didn't notice that one.

Revision history for this message
Mark Esler (eslerm) wrote :

Thank you for the thorough review and merge!

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/scripts/check-cves b/scripts/check-cves
index 0ce30ef..c00cd27 100755
--- a/scripts/check-cves
+++ b/scripts/check-cves
@@ -254,7 +254,7 @@ def import_debian(handler):
254 for cve in dsas[dsa]['cves']:254 for cve in dsas[dsa]['cves']:
255 if not cve_lib.CVE_RE.match(cve):255 if not cve_lib.CVE_RE.match(cve):
256 if args.verbose:256 if args.verbose:
257 print("Skipping %s, not well-formed?" % cve, file=sys.stderr)257 print(f"Skipping {cve}, not well-formed?", file=sys.stderr)
258 continue258 continue
259259
260 year = int(re.split('-', cve)[1])260 year = int(re.split('-', cve)[1])
@@ -275,27 +275,27 @@ def import_debian(handler):
275 cves[cve]['date'] = dsas[dsa]['date']275 cves[cve]['date'] = dsas[dsa]['date']
276276
277 if args.verbose:277 if args.verbose:
278 print("Processing %s: %s (%s)" % (dsa, dsas[dsa]['desc'], cves[cve]['date']), file=sys.stderr)278 print(f"Processing {dsa}: {dsas[dsa]['desc']} ({cves[cve]['date']})", file=sys.stderr)
279279
280 # Now pull in CVEs from the data/CVE/list280 # Now pull in CVEs from the data/CVE/list
281 for cve in handler.debian:281 for cve in handler.debian:
282 if args.verbose:282 if args.verbose:
283 print("[--- Processing %s ---]" % cve, file=sys.stderr)283 print(f"[--- Processing {cve} ---]", file=sys.stderr)
284284
285 if cve in cves:285 if cve in cves:
286 if args.verbose:286 if args.verbose:
287 print("Skipping %s, already found in DSA" % cve, file=sys.stderr)287 print(f"Skipping {cve}, already found in DSA", file=sys.stderr)
288 continue288 continue
289289
290 if not cve_lib.CVE_RE.match(cve):290 if not cve_lib.CVE_RE.match(cve):
291 if args.verbose:291 if args.verbose:
292 print("Skipping %s, not well-formed?" % cve, file=sys.stderr)292 print(f"Skipping {cve}, not well-formed?", file=sys.stderr)
293 continue293 continue
294294
295 year = int(re.split('-', cve)[1])295 year = int(re.split('-', cve)[1])
296 if year < cve_limit:296 if year < cve_limit:
297 if args.verbose:297 if args.verbose:
298 print("Skipping %s, year %d predates %d" % (cve, year, cve_limit), file=sys.stderr)298 print(f"Skipping {cve}, year {year} predates {cve_limit}", file=sys.stderr)
299 continue299 continue
300300
301 # If we already know about the CVE, skip it unless is mistriaged301 # If we already know about the CVE, skip it unless is mistriaged
@@ -305,7 +305,7 @@ def import_debian(handler):
305 handler.debian[cve]['desc'] = mistriaged_hint + handler.debian[cve]['desc']305 handler.debian[cve]['desc'] = mistriaged_hint + handler.debian[cve]['desc']
306 else:306 else:
307 if args.verbose:307 if args.verbose:
308 print("Skipping %s, already known" % cve, file=sys.stderr)308 print(f"Skipping {cve}, already known", file=sys.stderr)
309 continue309 continue
310310
311 if handler.debian[cve]['desc'] or handler.debian[cve]['state'] == 'FOUND':311 if handler.debian[cve]['desc'] or handler.debian[cve]['state'] == 'FOUND':
@@ -315,13 +315,13 @@ def import_debian(handler):
315 cves[cve]['subject'] = '[Unknown description]'315 cves[cve]['subject'] = '[Unknown description]'
316316
317 # just make something up. It'll get adjusted whenever mitre adds it317 # just make something up. It'll get adjusted whenever mitre adds it
318 date = "%s-12-31" % year318 date = f"{year}-12-31"
319 if year >= today.year:319 if year >= today.year:
320 date = "%s-%s-%s" % (today.year, today.month, today.day)320 date = f"{today.year}-{today.month}-{today.day}"
321 cves[cve]['date'] = datetime.strptime(date, "%Y-%m-%d")321 cves[cve]['date'] = datetime.strptime(date, "%Y-%m-%d")
322322
323 if args.verbose:323 if args.verbose:
324 print("Processing %s: %s (%s)" % (cve, handler.debian[cve]['desc'], cves[cve]['date']), file=sys.stderr)324 print(f"Processing {cve}: {handler.debian[cve]['desc']} ({cves[cve]['date']})", file=sys.stderr)
325325
326 nvd = convert_to_nvd(cves, lambda cve: cves[cve]['subject'])326 nvd = convert_to_nvd(cves, lambda cve: cves[cve]['subject'])
327 tmp = tempfile.NamedTemporaryFile(mode='w', prefix='debian-import_', suffix='.json', delete=False)327 tmp = tempfile.NamedTemporaryFile(mode='w', prefix='debian-import_', suffix='.json', delete=False)
@@ -397,12 +397,12 @@ def read_rhel8oval_file(f):
397 file for processing.397 file for processing.
398 '''398 '''
399 if not os.path.isfile(f):399 if not os.path.isfile(f):
400 print("'%s' not a file" % f, file=sys.stderr)400 print(f"'{f}' not a file", file=sys.stderr)
401 sys.exit(1)401 sys.exit(1)
402402
403 name = os.path.abspath(f + ".json")403 name = os.path.abspath(f + ".json")
404 if os.path.exists(name):404 if os.path.exists(name):
405 print("'%s' already exists" % name, file=sys.stderr)405 print(f"'{name}' already exists", file=sys.stderr)
406 sys.exit(1)406 sys.exit(1)
407407
408 parser = xml.sax.make_parser()408 parser = xml.sax.make_parser()
@@ -425,12 +425,12 @@ def read_locate_cves_output(f):
425 file for processing.425 file for processing.
426 '''426 '''
427 if not os.path.isfile(f):427 if not os.path.isfile(f):
428 print("'%s' not a file" % f, file=sys.stderr)428 print(f"'{f}' not a file", file=sys.stderr)
429 sys.exit(1)429 sys.exit(1)
430430
431 name = os.path.abspath(f + ".json")431 name = os.path.abspath(f + ".json")
432 if os.path.exists(name):432 if os.path.exists(name):
433 print("'%s' already exists" % name, file=sys.stderr)433 print(f"'{name}' already exists", file=sys.stderr)
434 sys.exit(1)434 sys.exit(1)
435435
436 with open(f) as _f:436 with open(f) as _f:
@@ -449,15 +449,15 @@ def read_locate_cves_output(f):
449 if line.startswith("Couldn't find CVE"):449 if line.startswith("Couldn't find CVE"):
450 cve = line.split()[2]450 cve = line.split()[2]
451 if not cve_lib.CVE_RE.match(cve):451 if not cve_lib.CVE_RE.match(cve):
452 print("Skipping malformed CVE: '%s' from '%s'" % (cve, f), file=sys.stderr)452 print(f"Skipping malformed CVE: '{cve}' from '{f}'", file=sys.stderr)
453 cve = None453 cve = None
454 elif cve in cves:454 elif cve in cves:
455 if args.verbose:455 if args.verbose:
456 print("Skipping duplicate '%s' from '%s'" % (cve, f), file=sys.stderr)456 print(f"Skipping duplicate '{cve}' from '{f}'", file=sys.stderr)
457 cve = None457 cve = None
458 else:458 else:
459 if args.verbose:459 if args.verbose:
460 print("Adding '%s'" % cve, file=sys.stderr)460 print(f"Adding '{cve}'", file=sys.stderr)
461 cves[cve] = dict()461 cves[cve] = dict()
462 continue462 continue
463463
@@ -469,7 +469,7 @@ def read_locate_cves_output(f):
469 date = " ".join(line.split(": ")[1].strip().split()[0:5])469 date = " ".join(line.split(": ")[1].strip().split()[0:5])
470 cves[cve]['date'] = datetime.strptime(date, "%a, %d %b %Y %H:%M:%S")470 cves[cve]['date'] = datetime.strptime(date, "%a, %d %b %Y %H:%M:%S")
471 except Exception:471 except Exception:
472 print("Could not process date '%s', skipping %s from '%s'" % (line, cve, f), file=sys.stderr)472 print(f"Could not process date '{line}', skipping {cve} from '{f}'", file=sys.stderr)
473 del cves[cve]473 del cves[cve]
474 cve = None474 cve = None
475 continue475 continue
@@ -491,11 +491,10 @@ def read_locate_cves_output(f):
491 # NOTE: while we can determine the url for the year/month/day, we491 # NOTE: while we can determine the url for the year/month/day, we
492 # cannot determine the specific message on that day. This gets us492 # cannot determine the specific message on that day. This gets us
493 # close though, so use it.493 # close though, so use it.
494 url = "http://www.openwall.com/lists/oss-security/%s" % (cves[cve]['date'].strftime("%Y/%m/%d"))494 url = "http://www.openwall.com/lists/oss-security/" + cves[cve]['date'].strftime('%Y/%m/%d')
495 cves[cve].setdefault('refs', [] + [url])495 cves[cve].setdefault('refs', [] + [url])
496496
497 nvd = convert_to_nvd(cves, lambda c: '''ML-Date: %s, ML-Subject: %s''' %497 nvd = convert_to_nvd(cves, lambda c: f'''ML-Date: {cves[c]['date']}, ML-Subject: {escape(cves[c]['subject'])}''')
498 (cves[c]['date'], escape(cves[c]['subject'])))
499498
500 tmp = tempfile.NamedTemporaryFile(mode='w', prefix='locate-cves-import_', suffix='.json', delete=False)499 tmp = tempfile.NamedTemporaryFile(mode='w', prefix='locate-cves-import_', suffix='.json', delete=False)
501 tmp.file.write(json.dumps(nvd))500 tmp.file.write(json.dumps(nvd))
@@ -510,7 +509,7 @@ def read_mbox_file(f):
510 And process through read_locate_cves_output()509 And process through read_locate_cves_output()
511 '''510 '''
512 if not os.path.isfile(f) and not os.path.isdir(f):511 if not os.path.isfile(f) and not os.path.isdir(f):
513 print("'%s' not a file" % f, file=sys.stderr)512 print(f"'{f}' not a file", file=sys.stderr)
514 sys.exit(1)513 sys.exit(1)
515514
516 child = subprocess.Popen(['./scripts/locate_cves.py', f], stdout=subprocess.PIPE, universal_newlines=True)515 child = subprocess.Popen(['./scripts/locate_cves.py', f], stdout=subprocess.PIPE, universal_newlines=True)
@@ -602,17 +601,23 @@ class CVEHandler(xml.sax.handler.ContentHandler):
602 timestamp = time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime())601 timestamp = time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime())
603602
604 # Append to timestamp file list603 # Append to timestamp file list
605 with open('%s/check-cves.log' % (destdir), 'a') as f:604 with open(f'{destdir}/check-cves.log', 'a') as f:
606 f.write('%s UTC - %s added, %s ignored, %s skipped, %s total - files: %s\n' %605 f.write(
607 (timestamp, self.num_added, self.num_ignored, self.num_skipped, self.num_added + self.num_ignored, [os.path.basename(x) for x in args.uris]))606 f"{timestamp} UTC - "
607 f"{self.num_added} added, "
608 f"{self.num_ignored} ignored, "
609 f"{self.num_skipped} skipped, "
610 f"{self.num_added + self.num_ignored} total - "
611 f"files: {[os.path.basename(x) for x in args.uris]}\n"
612 )
608613
609 def printReport(self):614 def printReport(self):
610 print('\n============================ Triage summary =============================')615 print('\n============================ Triage summary =============================')
611 print("\n %4d CVEs added" % self.num_added)616 print(f"\n {self.num_added: 4d} CVEs added")
612 print(" %4d CVEs ignored" % self.num_ignored)617 print(f" {self.num_ignored: 4d} CVEs ignored")
613 print(" %4d CVEs skipped" % self.num_skipped)618 print(f" {self.num_skipped: 4d} CVEs skipped")
614 print("---------------------------")619 print("---------------------------")
615 print("%5d total CVEs triaged" % (self.num_added + self.num_ignored))620 print(f"{self.num_added + self.num_ignored: 5d} total CVEs triaged")
616 updates_detected, updates_details = self.detect_updates_to_external_repositories()621 updates_detected, updates_details = self.detect_updates_to_external_repositories()
617 if updates_detected:622 if updates_detected:
618 print('\n====================== External updates detected ========================')623 print('\n====================== External updates detected ========================')
@@ -636,7 +641,7 @@ class CVEHandler(xml.sax.handler.ContentHandler):
636 if process.returncode == 0 and process.stdout:641 if process.returncode == 0 and process.stdout:
637 if process.stdout:642 if process.stdout:
638 updates_detected = True643 updates_detected = True
639 updates_details += "\n %s \n %s" % (repository_dir, process.stdout)644 updates_details += f"\n {repository_dir} \n {process.stdout}"
640 except subprocess.CalledProcessError as exception:645 except subprocess.CalledProcessError as exception:
641 print(exception)646 print(exception)
642 updates_detected = False647 updates_detected = False
@@ -657,11 +662,11 @@ class CVEHandler(xml.sax.handler.ContentHandler):
657 "data_version": "4.0"}662 "data_version": "4.0"}
658 for key in list(template_cve.keys()):663 for key in list(template_cve.keys()):
659 if key not in cve or cve[key] != template_cve[key]:664 if key not in cve or cve[key] != template_cve[key]:
660 raise KeyError("NVD JSON in '%s' seems invalid" % fp.name)665 raise KeyError(f"NVD JSON in '{fp.name}' seems invalid")
661666
662 metadata = cve["CVE_data_meta"]667 metadata = cve["CVE_data_meta"]
663 if not re.match(r'^CVE-\d{4}-\d{4,}$', metadata["ID"]):668 if not re.match(r'^CVE-\d{4}-\d{4,}$', metadata["ID"]):
664 print("Ignoring invalid CVE with ID '%s'" % metadata["ID"])669 print(f"Ignoring invalid CVE with ID '{metadata['ID']}'")
665 return670 return
666 self.curr_cve = metadata["ID"]671 self.curr_cve = metadata["ID"]
667672
@@ -693,7 +698,7 @@ class CVEHandler(xml.sax.handler.ContentHandler):
693 # check for expected fields698 # check for expected fields
694 for key in list(template_nvd.keys()):699 for key in list(template_nvd.keys()):
695 if key not in record or record[key] != template_nvd[key]:700 if key not in record or record[key] != template_nvd[key]:
696 raise KeyError("NVD JSON in '%s' seems invalid - missing key '%s'" % (fp.name, key))701 raise KeyError(f"NVD JSON in '{fp.name}' seems invalid - missing key '{key}'")
697 for item in record["CVE_Items"]:702 for item in record["CVE_Items"]:
698 self.curr_cvss = []703 self.curr_cvss = []
699 self.curr_refs = []704 self.curr_refs = []
@@ -787,7 +792,7 @@ class CVEHandler(xml.sax.handler.ContentHandler):
787 return792 return
788793
789 if self.curr_cve in self.cve_seen:794 if self.curr_cve in self.cve_seen:
790 print("Skipping repeat: %s" % (self.curr_cve), file=sys.stderr)795 print(f"Skipping repeat: {self.curr_cve}", file=sys.stderr)
791 return796 return
792 self.cve_seen.add(self.curr_cve)797 self.cve_seen.add(self.curr_cve)
793798
@@ -802,18 +807,20 @@ class CVEHandler(xml.sax.handler.ContentHandler):
802 return self.cve_list807 return self.cve_list
803808
804 def display_command_file_usage(self, f, line_prefix=''):809 def display_command_file_usage(self, f, line_prefix=''):
805 f.write('%sThe following commands can be used in this file:\n' % (line_prefix))810 # fmt: off
806 f.write('%s\n' % (line_prefix))811 f.write(f'{line_prefix}The following commands can be used in this file:\n')
807 f.write('%s* Add a new CVE to the tracker:\n' % (line_prefix))812 f.write(f'{line_prefix}\n')
808 f.write('%s <CVE> add <PRIORITY> <PACKAGE> [PACKAGE] ...\n' % (line_prefix))813 f.write(f'{line_prefix}* Add a new CVE to the tracker:\n')
809 f.write('%s* Add a new CVE to the tracker and open it in your editor:\n' % (line_prefix))814 f.write(f'{line_prefix} <CVE> add <PRIORITY> <PACKAGE> [PACKAGE] ...\n')
810 f.write('%s <CVE> edit <PRIORITY> <PACKAGE> [PACKAGE] ...\n' % (line_prefix))815 f.write(f'{line_prefix}* Add a new CVE to the tracker and open it in your editor:\n')
811 f.write('%s* Unembargo a CVE that is now public:\n' % (line_prefix))816 f.write(f'{line_prefix} <CVE> edit <PRIORITY> <PACKAGE> [PACKAGE] ...\n')
812 f.write('%s <CVE> unembargo>\n' % (line_prefix))817 f.write(f'{line_prefix}* Unembargo a CVE that is now public:\n')
813 f.write('%s* Permanently ignore a CVE:\n' % (line_prefix))818 f.write(f'{line_prefix} <CVE> unembargo>\n')
814 f.write('%s <CVE> ignore <REASON>\n' % (line_prefix))819 f.write(f'{line_prefix}* Permanently ignore a CVE:\n')
815 f.write('%s* Temporarily skip over a CVE:\n' % (line_prefix))820 f.write(f'{line_prefix} <CVE> ignore <REASON>\n')
816 f.write('%s <CVE> skip\n\n' % (line_prefix))821 f.write(f'{line_prefix}* Temporarily skip over a CVE:\n')
822 f.write(f'{line_prefix} <CVE> skip\n\n')
823 # fmt: on
817 f.flush()824 f.flush()
818825
819 def find_hint_in_external_subprojects(self, software_hints_from_cve_description):826 def find_hint_in_external_subprojects(self, software_hints_from_cve_description):
@@ -861,24 +868,24 @@ class CVEHandler(xml.sax.handler.ContentHandler):
861 print('=================================end details==================================')868 print('=================================end details==================================')
862 # Display CVE information869 # Display CVE information
863 if self.cve_data[cve]['public']:870 if self.cve_data[cve]['public']:
864 print(' Published: %s' % (self.cve_data[cve]['public']))871 print(f" Published: {self.cve_data[cve]['public']}")
865 for ref in self.cve_data[cve]['refs']:872 for ref in self.cve_data[cve]['refs']:
866 print(' %s: %s' % (ref[0], ref[1]), end='')873 print(f' {ref[0]}: {ref[1]}', end='')
867 # Do not repeat URL if it matches the contents of the reference874 # Do not repeat URL if it matches the contents of the reference
868 if ref[2] and ref[1].strip() != ref[2].strip():875 if ref[2] and ref[1].strip() != ref[2].strip():
869 print(' %s' % (ref[2]), end='')876 print(f' {ref[2]}', end='')
870 print()877 print()
871 if wrap_desc:878 if wrap_desc:
872 print('%s' % _wrap_desc(self.cve_data[cve]['desc']))879 print(_wrap_desc(self.cve_data[cve]['desc']))
873 else:880 else:
874 print('\n======================== CVE details ==========================')881 print('\n======================== CVE details ==========================')
875 print(' %s' % cve)882 print(f' {cve}')
876 print(' %s' % (self.cve_data[cve]['desc']))883 print(f" {self.cve_data[cve]['desc']}")
877 for cvss in self.cve_data[cve]['cvss']:884 for cvss in self.cve_data[cve]['cvss']:
878 print(' CVSS (%s): %s [%.1f]' % (cvss['source'], cvss['vector'], cvss['baseScore']))885 print(f" CVSS ({cvss['source']}): {cvss['vector']} [{cvss['baseScore']: .1f}]")
879 if self.debian and cve in self.debian:886 if self.debian and cve in self.debian:
880 print('\n======================= Debian details ========================')887 print('\n======================= Debian details ========================')
881 print(' Debian CVE Tracker: %s' % (self.debian[cve]['state']))888 print(f" Debian CVE Tracker: {self.debian[cve]['state']}")
882 if len(self.debian[cve]['note']):889 if len(self.debian[cve]['note']):
883 print("\t" + "\n\t".join(self.debian[cve]['note']))890 print("\t" + "\n\t".join(self.debian[cve]['note']))
884 for pkg in self.debian[cve]['pkgs']:891 for pkg in self.debian[cve]['pkgs']:
@@ -889,23 +896,23 @@ class CVEHandler(xml.sax.handler.ContentHandler):
889 info.append(self.debian[cve]['pkgs'][pkg]['bug'])896 info.append(self.debian[cve]['pkgs'][pkg]['bug'])
890 if self.debian[cve]['pkgs'][pkg]['note']:897 if self.debian[cve]['pkgs'][pkg]['note']:
891 info.append(self.debian[cve]['pkgs'][pkg]['note'])898 info.append(self.debian[cve]['pkgs'][pkg]['note'])
892 print(" Debian: %s: %s (%s)" % (pkg, self.debian[cve]['pkgs'][pkg]['state'], "; ".join(info)))899 print(f" Debian: {pkg}: {self.debian[cve]['pkgs'][pkg]['state']} ({'; '.join(info)})")
893 # Display version and component details for Ubuntu's pkg900 # Display version and component details for Ubuntu's pkg
894 answer = source_map.madison(source, pkg)901 answer = source_map.madison(source, pkg)
895 for name in sorted(answer.keys()):902 for name in sorted(answer.keys()):
896 for pkg in sorted(answer[name].keys()):903 for pkg in sorted(answer[name].keys()):
897 print(' Ubuntu: %s | %s | %s' % (pkg, answer[name][pkg], name))904 print(f' Ubuntu: {pkg} | {answer[name][pkg]} | {name}')
898 # no debian info, display possible commented ignore command when905 # no debian info, display possible commented ignore command when
899 # using command file (i.e. wrap_desc is true)906 # using command file (i.e. wrap_desc is true)
900 if (self.debian[cve]['state'] == 'RESERVED' or self.debian[cve]['state'] == None) and wrap_desc:907 if (self.debian[cve]['state'] == 'RESERVED' or self.debian[cve]['state'] == None) and wrap_desc:
901 proposed_ignore = self.ignore_suggestion.get_ignore_suggestion(self.cve_data[cve]['desc'])908 proposed_ignore = self.ignore_suggestion.get_ignore_suggestion(self.cve_data[cve]['desc'])
902 print('%s ignore "%s"' % (cve, proposed_ignore))909 print(f'{cve} ignore "{proposed_ignore}"')
903 # debian rejected, so offer to reject by ignoring when using command file (i.e. wrap_desc is true)910 # debian rejected, so offer to reject by ignoring when using command file (i.e. wrap_desc is true)
904 if (self.debian[cve]['state'] == 'REJECTED' and wrap_desc):911 if (self.debian[cve]['state'] == 'REJECTED' and wrap_desc):
905 print('%s ignore "%s"' % (cve, "REJECTED"))912 print(f'{cve} ignore "REJECTED"')
906 else:913 else:
907 proposed_ignore = self.ignore_suggestion.get_ignore_suggestion(self.cve_data[cve]['desc'])914 proposed_ignore = self.ignore_suggestion.get_ignore_suggestion(self.cve_data[cve]['desc'])
908 print('%s ignore %s' % (cve, proposed_ignore))915 print(f'{cve} ignore {proposed_ignore}')
909916
910 software_hints_from_cve_desc = self.get_software_hints_from_cve_description(self.cve_data[cve]["desc"])917 software_hints_from_cve_desc = self.get_software_hints_from_cve_description(self.cve_data[cve]["desc"])
911 if software_hints_from_cve_desc:918 if software_hints_from_cve_desc:
@@ -953,7 +960,7 @@ class CVEHandler(xml.sax.handler.ContentHandler):
953 if self.debian[cve]['pkgs'][pkg]['state'] == '<itp>':960 if self.debian[cve]['pkgs'][pkg]['state'] == '<itp>':
954 # software has not been admitted into debian961 # software has not been admitted into debian
955 action = 'ignore'962 action = 'ignore'
956 reason = '%s: <itp> (dbug %s)' % (pkg, self.debian[cve]['pkgs'][pkg]['bug'])963 reason = f"{pkg}: <itp> (dbug {self.debian[cve]['pkgs'][pkg]['bug']})"
957 if self.debian[cve]['state'] == 'REJECTED':964 if self.debian[cve]['state'] == 'REJECTED':
958 action = 'ignore'965 action = 'ignore'
959 reason = 'REJECTED'966 reason = 'REJECTED'
@@ -1003,7 +1010,7 @@ class CVEHandler(xml.sax.handler.ContentHandler):
1003 def human_process_cve(self, cve, action='skip', reason='', package=''):1010 def human_process_cve(self, cve, action='skip', reason='', package=''):
1004 info = ''1011 info = ''
1005 while info == "" or not info[0] in ['i', 'a', 's', 'q', 'r']:1012 while info == "" or not info[0] in ['i', 'a', 's', 'q', 'r']:
1006 prompt_user('\nA]dd (or R]epeat), I]gnore forever, S]kip for now, or Q]uit? [%s] ' % (action))1013 prompt_user(f'\nA]dd (or R]epeat), I]gnore forever, S]kip for now, or Q]uit? [{action}] ')
1007 info = sys.stdin.readline().strip().lower()1014 info = sys.stdin.readline().strip().lower()
1008 if info == "":1015 if info == "":
1009 info = action1016 info = action
@@ -1023,7 +1030,7 @@ class CVEHandler(xml.sax.handler.ContentHandler):
1023 if package == "":1030 if package == "":
1024 package = self.saved_package1031 package = self.saved_package
1025 if package != "":1032 if package != "":
1026 prompt_user('[%s] ' % (package))1033 prompt_user(f'[{package}] ')
1027 info = sys.stdin.readline().strip()1034 info = sys.stdin.readline().strip()
1028 if info == '':1035 if info == '':
1029 info = package1036 info = package
@@ -1037,19 +1044,19 @@ class CVEHandler(xml.sax.handler.ContentHandler):
1037 self.saved_cve = cve1044 self.saved_cve = cve
10381045
1039 print('\n===================== Dependant packages ======================')1046 print('\n===================== Dependant packages ======================')
1040 print(' Detecting packages built using: %s...' % info, end='')1047 print(f' Detecting packages built using: {info}...', end='')
1041 sys.stdout.flush()1048 sys.stdout.flush()
1042 built_using = ""1049 built_using = ""
1043 try:1050 try:
1044 built_using = get_built_using(info)1051 built_using = get_built_using(info)
1045 except Exception as e:1052 except Exception as e:
1046 print("ERROR: %s" % e, file=sys.stderr)1053 print(f"ERROR: {e}", file=sys.stderr)
1047 pass # for now just show the error but don't break triage1054 pass # for now just show the error but don't break triage
10481055
1049 if built_using != "":1056 if built_using != "":
1050 print("found:\n")1057 print("found:\n")
1051 print("%s" % source_map.get_built_using_header())1058 print(source_map.get_built_using_header())
1052 print("%s" % built_using)1059 print(built_using)
1053 print("IMPORTANT: the above packages are candidates for rebuilds when fixes are applied to:")1060 print("IMPORTANT: the above packages are candidates for rebuilds when fixes are applied to:")
1054 print(" %s" % "\n ".join(info))1061 print(" %s" % "\n ".join(info))
1055 else:1062 else:
@@ -1071,7 +1078,7 @@ class CVEHandler(xml.sax.handler.ContentHandler):
1071 prompts.append(choice)1078 prompts.append(choice)
10721079
1073 for i in range(0, len(prompts)):1080 for i in range(0, len(prompts)):
1074 print(' %s) %s' % (chr(97 + i), prompts[i]))1081 print(f" {chr(97 + i)}) {prompts[i]}")
1075 prompt_user(' > ')1082 prompt_user(' > ')
10761083
1077 info = sys.stdin.readline().strip()1084 info = sys.stdin.readline().strip()
@@ -1113,13 +1120,13 @@ class CVEHandler(xml.sax.handler.ContentHandler):
1113 try:1120 try:
1114 (cve, action) = (args[0].upper(), args[1].lower())1121 (cve, action) = (args[0].upper(), args[1].lower())
1115 except IndexError:1122 except IndexError:
1116 raise ValueError('Invalid formatting on line %d:\n%s' % (line_num, orig_line))1123 raise ValueError(f'Invalid formatting on line {line_num}:\n{orig_line}')
11171124
1118 if not cve.startswith('CVE-'):1125 if not cve.startswith('CVE-'):
1119 # The first arg should look like a CVE ID1126 # The first arg should look like a CVE ID
1120 raise ValueError('Invalid CVE ID formatting (%s) on line %d:\n%s' % (cve, line_num, orig_line))1127 raise ValueError(f'Invalid CVE ID formatting ({cve}) on line {line_num}:\n{orig_line}')
1121 elif cve in cves:1128 elif cve in cves:
1122 raise ValueError('Performing multiple operations on the same CVE (%s) is not supported (line %d):\n%s' % (cve, line_num, orig_line))1129 raise ValueError(f'Performing multiple operations on the same CVE ({cve}) is not supported (line {line_num}):\n{orig_line}')
1123 cves.append(cve)1130 cves.append(cve)
11241131
1125 if action == 'add' or action == 'edit':1132 if action == 'add' or action == 'edit':
@@ -1130,13 +1137,13 @@ class CVEHandler(xml.sax.handler.ContentHandler):
1130 priority = args[0].lower()1137 priority = args[0].lower()
1131 packages = args[1:]1138 packages = args[1:]
1132 except IndexError:1139 except IndexError:
1133 raise ValueError('Invalid add command on line %d:\n%s' % (line_num, orig_line))1140 raise ValueError(f'Invalid add command on line {line_num}:\n{orig_line}')
11341141
1135 if not priority in cve_lib.priorities and not priority == 'untriaged':1142 if not priority in cve_lib.priorities and not priority == 'untriaged':
1136 raise ValueError('Invalid priority on line %d:\n%s' % (line_num, orig_line))1143 raise ValueError(f'Invalid priority on line {line_num}:\n{orig_line}')
11371144
1138 if os.path.exists('%s/active/%s' % (destdir, cve)):1145 if os.path.exists(f'{destdir}/active/{cve}'):
1139 raise ValueError('Updating an existing CVE is not supported (line %d):\n%s' % (line_num, orig_line))1146 raise ValueError(f'Updating an existing CVE is not supported (line {line_num}):\n{orig_line}')
11401147
1141 if preprocess:1148 if preprocess:
1142 continue1149 continue
@@ -1150,10 +1157,10 @@ class CVEHandler(xml.sax.handler.ContentHandler):
1150 _spawn_editor(cve_path)1157 _spawn_editor(cve_path)
1151 elif action == 'unembargo':1158 elif action == 'unembargo':
1152 if cve not in EmbargoList:1159 if cve not in EmbargoList:
1153 raise ValueError('CVE %s is not in the embargo database (line %d):\n%s' % (cve, line_num, orig_line))1160 raise ValueError(f'CVE {cve} is not in the embargo database (line {line_num}):\n{orig_line}')
11541161
1155 if os.path.exists(os.path.join('active', cve)):1162 if os.path.exists(os.path.join('active', cve)):
1156 raise ValueError('Cannot unembargo %s because it already exists in the active directory (line %d):\n%s' % (cve, line_num, orig_line))1163 raise ValueError(f'Cannot unembargo {cve} because it already exists in the active directory (line {line_num}):\n{orig_line}')
11571164
1158 if preprocess:1165 if preprocess:
1159 continue1166 continue
@@ -1164,7 +1171,7 @@ class CVEHandler(xml.sax.handler.ContentHandler):
1164 try:1171 try:
1165 reason = args[2]1172 reason = args[2]
1166 except IndexError:1173 except IndexError:
1167 raise ValueError('Invalid ignore command on line %d:\n%s' % (line_num, orig_line))1174 raise ValueError(f'Invalid ignore command on line {line_num}:\n{orig_line}')
11681175
1169 if preprocess:1176 if preprocess:
1170 continue1177 continue
@@ -1173,7 +1180,7 @@ class CVEHandler(xml.sax.handler.ContentHandler):
1173 elif action == 'skip':1180 elif action == 'skip':
1174 # If the CVE should be skipped, no arguments are allowed1181 # If the CVE should be skipped, no arguments are allowed
1175 if len(args) > 2:1182 if len(args) > 2:
1176 raise ValueError('Invalid skip command on line %d:\n%s' % (line_num, orig_line))1183 raise ValueError(f'Invalid skip command on line {line_num}:\n{orig_line}')
11771184
1178 if preprocess:1185 if preprocess:
1179 continue1186 continue
@@ -1181,7 +1188,7 @@ class CVEHandler(xml.sax.handler.ContentHandler):
1181 self.skip_cve()1188 self.skip_cve()
1182 else:1189 else:
1183 # The second arg must be a known action1190 # The second arg must be a known action
1184 raise ValueError('Unknown action (%s) on line %d:\n%s' % (action, line_num, orig_line))1191 raise ValueError(f'Unknown action ({action}) on line {line_num}:\n{orig_line}')
11851192
1186 def preprocess_cve(self, cve):1193 def preprocess_cve(self, cve):
1187 desc = ''1194 desc = ''
@@ -1195,20 +1202,20 @@ class CVEHandler(xml.sax.handler.ContentHandler):
1195 desc += '# =================================end details==================================\n'1202 desc += '# =================================end details==================================\n'
1196 # Display CVE information1203 # Display CVE information
1197 if self.cve_data[cve]['public']:1204 if self.cve_data[cve]['public']:
1198 desc += '# Published: %s\n' % (self.cve_data[cve]['public'])1205 desc += f'# Published: {self.cve_data[cve]["public"]}\n'
1199 for ref in self.cve_data[cve]['refs']:1206 for ref in self.cve_data[cve]['refs']:
1200 desc += '# %s: %s' % (ref[0], ref[1])1207 desc += f'# {ref[0]}: {ref[1]}'
1201 # Do not repeat URL if it matches the contents of the reference1208 # Do not repeat URL if it matches the contents of the reference
1202 if ref[2] and ref[1].strip() != ref[2].strip():1209 if ref[2] and ref[1].strip() != ref[2].strip():
1203 desc += ' %s' % (ref[2])1210 desc += f' {ref[2]}'
1204 desc += '\n'1211 desc += '\n'
1205 for line in _wrap_desc(self.cve_data[cve]['desc']).split('\n'):1212 for line in _wrap_desc(self.cve_data[cve]['desc']).split('\n'):
1206 desc += '# %s\n' % line1213 desc += f'# {line}\n'
1207 if self.debian and cve in self.debian:1214 if self.debian and cve in self.debian:
1208 desc += '# Debian CVE Tracker: %s\n' % (self.debian[cve]['state'])1215 desc += f"# Debian CVE Tracker: {self.debian[cve]['state']}\n"
1209 if len(self.debian[cve]['note']):1216 if len(self.debian[cve]['note']):
1210 for note in self.debian[cve]['note']:1217 for note in self.debian[cve]['note']:
1211 desc += '# \t%s\n' % note1218 desc += f'# \t{note}\n'
1212 for pkg in self.debian[cve]['pkgs']:1219 for pkg in self.debian[cve]['pkgs']:
1213 info = []1220 info = []
1214 if self.debian[cve]['pkgs'][pkg]['priority']:1221 if self.debian[cve]['pkgs'][pkg]['priority']:
@@ -1222,7 +1229,7 @@ class CVEHandler(xml.sax.handler.ContentHandler):
1222 answer = source_map.madison(source, pkg)1229 answer = source_map.madison(source, pkg)
1223 for name in sorted(answer.keys()):1230 for name in sorted(answer.keys()):
1224 for pkg in sorted(answer[name].keys()):1231 for pkg in sorted(answer[name].keys()):
1225 desc += '# Ubuntu: %s | %s | %s\n' % (pkg, answer[name][pkg], name)1232 desc += f'# Ubuntu: {pkg} | {answer[name][pkg]} | {name}\n'
12261233
1227 action = 'skip'1234 action = 'skip'
1228 data = ""1235 data = ""
@@ -1240,13 +1247,13 @@ class CVEHandler(xml.sax.handler.ContentHandler):
1240 action = 'add'1247 action = 'add'
1241 data = " ".join(self.debian[cve]['pkgs'])1248 data = " ".join(self.debian[cve]['pkgs'])
12421249
1243 print('%s %s %s\n%s' % (action, cve, data, desc))1250 print(f'{action} {cve} {data}\n{desc}')
12441251
1245 def add_cve(self, cve, packages, priority=None):1252 def add_cve(self, cve, packages, priority=None):
1246 # remove from not-for-us.txt if adding and ensure we remove any1253 # remove from not-for-us.txt if adding and ensure we remove any
1247 # mistriaged_hint from the description1254 # mistriaged_hint from the description
1248 if cve in CVEIgnoreNotForUsSet:1255 if cve in CVEIgnoreNotForUsSet:
1249 cmd = ['sed', '-i', '/^%s #.*$/d' % cve, './ignored/not-for-us.txt']1256 cmd = ['sed', '-i', f'/^{cve} #.*$/d', './ignored/not-for-us.txt']
1250 subprocess.call(cmd)1257 subprocess.call(cmd)
1251 self.cve_data[cve]['desc'] = self.cve_data[cve]['desc'].replace(mistriaged_hint, '')1258 self.cve_data[cve]['desc'] = self.cve_data[cve]['desc'].replace(mistriaged_hint, '')
12521259
@@ -1294,7 +1301,7 @@ class CVEHandler(xml.sax.handler.ContentHandler):
1294 elif self.debian[cve]['pkgs'][pkg]['bug']:1301 elif self.debian[cve]['pkgs'][pkg]['bug']:
1295 bug = self.debian[cve]['pkgs'][pkg]['bug']1302 bug = self.debian[cve]['pkgs'][pkg]['bug']
1296 if bug:1303 if bug:
1297 url = "http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=%s" % bug1304 url = "http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=" + bug
1298 if url not in bug_urls:1305 if url not in bug_urls:
1299 bug_urls.append(url)1306 bug_urls.append(url)
13001307
@@ -1330,7 +1337,7 @@ class CVEHandler(xml.sax.handler.ContentHandler):
1330 self.debian[cve]['pkgs'][pkg]['state']:1337 self.debian[cve]['pkgs'][pkg]['state']:
1331 if re.search(r'^[0-9]', self.debian[cve]['pkgs'][pkg]['state']):1338 if re.search(r'^[0-9]', self.debian[cve]['pkgs'][pkg]['state']):
1332 fixed_version = self.debian[cve]['pkgs'][pkg]['state']1339 fixed_version = self.debian[cve]['pkgs'][pkg]['state']
1333 fixed_in = ",%s" % fixed_version1340 fixed_in = f",{fixed_version}"
13341341
1335 # Now see if we can correlate this to an Ubuntu version1342 # Now see if we can correlate this to an Ubuntu version
1336 answer = source_map.madison(source, pkg)1343 answer = source_map.madison(source, pkg)
@@ -1344,20 +1351,20 @@ class CVEHandler(xml.sax.handler.ContentHandler):
1344 if dpkg_compare_versions(version, 'ge', fixed_version):1351 if dpkg_compare_versions(version, 'ge', fixed_version):
1345 if rel == cve_lib.devel_release:1352 if rel == cve_lib.devel_release:
1346 rel = 'devel'1353 rel = 'devel'
1347 fixed_in += ",%s,%s" % (rel, version)1354 fixed_in += f",{rel},{version}"
1348 break1355 break
1349 elif self.debian[cve]['pkgs'][pkg]['state'].startswith('<not-affected>') and \1356 elif self.debian[cve]['pkgs'][pkg]['state'].startswith('<not-affected>') and \
1350 len(self.debian[cve]['pkgs'][pkg]['priority']) > 0:1357 len(self.debian[cve]['pkgs'][pkg]['priority']) > 0:
1351 # capture that debian believes their version is unaffected1358 # capture that debian believes their version is unaffected
1352 not_affected.append((pkg, "debian: %s" % self.debian[cve]['pkgs'][pkg]['priority']))1359 not_affected.append(pkg, f"debian: {self.debian[cve]['pkgs'][pkg]['priority']}")
1353 cmd += ['-p', "%s%s" % (pkg, fixed_in)]1360 cmd += ['-p', f"{pkg}{fixed_in}"]
13541361
1355 subprocess.call(cmd)1362 subprocess.call(cmd)
1356 for (pkg, reason) in not_affected:1363 for (pkg, reason) in not_affected:
1357 cmd = ['./scripts/mass-cve-edit', '-p', pkg, '-r', 'upstream', '-s', 'not-affected', '-v', reason, cve]1364 cmd = ['./scripts/mass-cve-edit', '-p', pkg, '-r', 'upstream', '-s', 'not-affected', '-v', reason, cve]
1358 subprocess.call(cmd)1365 subprocess.call(cmd)
1359 self.num_added += 11366 self.num_added += 1
1360 return './active/%s' % cve1367 return f'./active/{cve}'
13611368
1362 def unembargo_cve(self, cve):1369 def unembargo_cve(self, cve):
1363 # unembargo a cve now public1370 # unembargo a cve now public
@@ -1368,8 +1375,8 @@ class CVEHandler(xml.sax.handler.ContentHandler):
1368 # Append to ignore list unless is already in CVEIgnoreList and then1375 # Append to ignore list unless is already in CVEIgnoreList and then
1369 # append to the ignored/ignore-mistriaged.txt1376 # append to the ignored/ignore-mistriaged.txt
1370 txtfile = 'ignore-mistriaged.txt' if cve in CVEIgnoreNotForUsSet else 'not-for-us.txt'1377 txtfile = 'ignore-mistriaged.txt' if cve in CVEIgnoreNotForUsSet else 'not-for-us.txt'
1371 with open('%s/ignored/%s' % (destdir, txtfile), 'a') as f:1378 with open(f'{destdir}/ignored/{txtfile}', 'a') as f:
1372 f.write('%s # %s\n' % (cve, reason))1379 f.write(f'{cve} # {reason}\n')
13731380
1374 self.num_ignored += 11381 self.num_ignored += 1
13751382
@@ -1428,7 +1435,7 @@ if args.cve:
1428 continue1435 continue
1429 # error out if is ignored1436 # error out if is ignored
1430 if cve in CVEIgnoreList:1437 if cve in CVEIgnoreList:
1431 print("%s already exists in UCT - please remove it then retriage." % cve)1438 print(f"{cve} already exists in UCT - please remove it then retriage.")
1432 sys.exit(1)1439 sys.exit(1)
1433 specific_cves.add(cve)1440 specific_cves.add(cve)
14341441
@@ -1453,7 +1460,7 @@ if (args.import_missing_debian or args.mistriaged) and handler.debian is not Non
14531460
14541461
1455for uri in args.uris:1462for uri in args.uris:
1456 print('Loading %s ...' % (uri), file=sys.stderr)1463 print(f'Loading {uri} ...', file=sys.stderr)
1457 if '://' in uri:1464 if '://' in uri:
1458 readable = urllib.request.urlopen(uri)1465 readable = urllib.request.urlopen(uri)
1459 else:1466 else:
@@ -1464,7 +1471,7 @@ for uri in args.uris:
1464 else:1471 else:
1465 parser.parse(readable)1472 parser.parse(readable)
1466 except xml.sax._exceptions.SAXParseException as e:1473 except xml.sax._exceptions.SAXParseException as e:
1467 print("\n\nWARNING: %s is malformed:\n%s" % (uri, e))1474 print(f"\n\nWARNING: {uri} is malformed:\n{e}")
1468 print("Aborting", file=sys.stderr)1475 print("Aborting", file=sys.stderr)
1469 sys.exit(1)1476 sys.exit(1)
1470 print('')1477 print('')
@@ -1490,17 +1497,17 @@ def refresh_cves(cve_refresh_list, full_refresh=True):
1490 cvsss = handler.cve_data[cve]['cvss']1497 cvsss = handler.cve_data[cve]['cvss']
1491 except:1498 except:
1492 if args.verbose:1499 if args.verbose:
1493 print('%s not listed in XML' % (cve), file=sys.stderr)1500 print(f'{cve} not listed in XML', file=sys.stderr)
14941501
1495 # Find the on-disk CVE file1502 # Find the on-disk CVE file
1496 cvefile = ""1503 cvefile = ""
1497 for status in ['active', 'retired', 'ignored']:1504 for status in ['active', 'retired', 'ignored']:
1498 check = '%s/%s/%s' % (destdir, status, cve)1505 check = f'{destdir}/{status}/{cve}'
1499 if os.path.exists(check):1506 if os.path.exists(check):
1500 cvefile = check1507 cvefile = check
1501 break1508 break
1502 if cvefile == "":1509 if cvefile == "":
1503 print('local dirs missing %s?!' % (cve), file=sys.stderr)1510 print(f'local dirs missing {cve}?!', file=sys.stderr)
1504 continue1511 continue
15051512
1506 # Load CVE1513 # Load CVE
@@ -1524,14 +1531,14 @@ def refresh_cves(cve_refresh_list, full_refresh=True):
1524 if data['Description'].strip() != desc:1531 if data['Description'].strip() != desc:
1525 cve_lib.update_multiline_field(cvefile, 'Description', desc)1532 cve_lib.update_multiline_field(cvefile, 'Description', desc)
1526 updated = True1533 updated = True
1527 debug("updated description for %s" % (cvefile))1534 debug(f"updated description for {cvefile}")
15281535
1529 # Update Publication Date if it needs it1536 # Update Publication Date if it needs it
1530 if public:1537 if public:
1531 if 'PublicDate' not in data or ('PublicDate' in data and data['PublicDate'] != public):1538 if 'PublicDate' not in data or ('PublicDate' in data and data['PublicDate'] != public):
1532 cve_lib.update_field(cvefile, 'PublicDate', public)1539 cve_lib.update_field(cvefile, 'PublicDate', public)
1533 updated = True1540 updated = True
1534 debug("updated pubdate for %s" % (cvefile))1541 debug(f"updated pubdate for {cvefile}")
15351542
1536 # Add CVE Reference, if it's missing1543 # Add CVE Reference, if it's missing
1537 if 'References' in data and re.match(r'^CVE-\d+-\d+$', cve):1544 if 'References' in data and re.match(r'^CVE-\d+-\d+$', cve):
@@ -1539,19 +1546,19 @@ def refresh_cves(cve_refresh_list, full_refresh=True):
1539 if mitre_ref not in data['References']:1546 if mitre_ref not in data['References']:
1540 cve_lib.add_reference(cvefile, mitre_ref)1547 cve_lib.add_reference(cvefile, mitre_ref)
1541 updated = True1548 updated = True
1542 debug("updated reference for %s" % (cvefile))1549 debug(f"updated reference for {cvefile}")
15431550
1544 # Update CVSS if needs it1551 # Update CVSS if needs it
1545 for entry in cvsss:1552 for entry in cvsss:
1546 try:1553 try:
1547 updated |= cve_lib.add_cvss(cvefile, entry['source'], entry['vector'])1554 updated |= cve_lib.add_cvss(cvefile, entry['source'], entry['vector'])
1548 debug("updated cvss for %s" % (cvefile))1555 debug(f"updated cvss for {cvefile}")
1549 except KeyError:1556 except KeyError:
1550 # we might not have a vector, in this case continue1557 # we might not have a vector, in this case continue
1551 pass1558 pass
15521559
1553 if updated:1560 if updated:
1554 print("Refreshed %s" % (cvefile), file=sys.stderr)1561 print(f"Refreshed {cvefile}", file=sys.stderr)
15551562
15561563
1557if args.refresh or args.score_refresh:1564if args.refresh or args.score_refresh:
@@ -1608,8 +1615,8 @@ for cve in new_cves:
16081615
1609 if not experimental:1616 if not experimental:
1610 print('\n***********************************************************************')1617 print('\n***********************************************************************')
1611 print(' %s (%d/%d: %d%%)' % (cve, count, total, (count * 100 / total)))1618 print(f" {cve} ({count}/{total}: {int(count * 100 / total)}%)")
1612 print(' https://cve.mitre.org/cgi-bin/cvename.cgi?name=%s' % (cve))1619 print(f" https://cve.mitre.org/cgi-bin/cvename.cgi?name={cve}")
1613 print('***********************************************************************')1620 print('***********************************************************************')
1614 handler.display_cve(cve, file=fout)1621 handler.display_cve(cve, file=fout)
1615 (action, reason, packages) = handler.get_cve_suggestions(cve)1622 (action, reason, packages) = handler.get_cve_suggestions(cve)
@@ -1619,16 +1626,16 @@ for cve in new_cves:
1619 else:1626 else:
1620 line_prefix = '# '1627 line_prefix = '# '
16211628
1622 fout.write('%s%s\n#\n' % (line_prefix, cve))1629 fout.write('{line_prefix}{cve}\n#\n')
1623 handler.display_cve(cve, file=fout, line_prefix=line_prefix, wrap_desc=True)1630 handler.display_cve(cve, file=fout, line_prefix=line_prefix, wrap_desc=True)
16241631
1625 (action, reason, packages) = handler.get_cve_suggestions(cve)1632 (action, reason, packages) = handler.get_cve_suggestions(cve)
1626 suggestion = '%s %s' % (cve, action)1633 suggestion = f'{cve} {action}'
1627 if reason:1634 if reason:
1628 suggestion += ' %s' % (reason)1635 suggestion += f' {reason}'
1629 elif action == 'add':1636 elif action == 'add':
1630 suggestion += ' untriaged %s' % (packages)1637 suggestion += f' untriaged {packages}'
1631 fout.write('%s\n\n' % (suggestion))1638 fout.write(f'{suggestion}\n\n')
16321639
1633if experimental:1640if experimental:
1634 fout.flush()1641 fout.flush()
@@ -1636,7 +1643,7 @@ if experimental:
1636 assert((total == 0 and count == 0) or (total > 0 and count >= 0))1643 assert((total == 0 and count == 0) or (total > 0 and count >= 0))
1637 # no need to spawn editor if no CVEs listed1644 # no need to spawn editor if no CVEs listed
1638 if count > 0:1645 if count > 0:
1639 prompt_user('Asking user to handle %d CVEs...' % count)1646 prompt_user(f'Asking user to handle {count} CVEs...')
1640 _spawn_editor(fout.name)1647 _spawn_editor(fout.name)
1641 else:1648 else:
1642 prompt_user('Not spawning editor as no CVEs to process')1649 prompt_user('Not spawning editor as no CVEs to process')
@@ -1645,8 +1652,7 @@ if experimental:
1645 handler.process_command_file(fout, preprocess=True)1652 handler.process_command_file(fout, preprocess=True)
1646 break1653 break
1647 except Exception as e:1654 except Exception as e:
1648 print('Error encountered while processing the command file!', file=sys.stderr)1655 print(f'Error encountered while processing the command file!\n{e}', file=sys.stderr)
1649 print('%s' % e, file=sys.stderr)
1650 print('Enter "quit" to lose all work or anything else to re-edit and try again: ', end='', file=sys.stderr)1656 print('Enter "quit" to lose all work or anything else to re-edit and try again: ', end='', file=sys.stderr)
1651 sys.stderr.flush()1657 sys.stderr.flush()
1652 response = sys.stdin.readline().strip().lower()1658 response = sys.stdin.readline().strip().lower()

Subscribers

People subscribed via source and target branches