From 9d36be993d2db2f099372f7252b32a2e53621bf8 Mon Sep 17 00:00:00 2001 From: Emilio Pozuelo Monfort Date: Fri, 17 Mar 2023 10:06:09 +0100 Subject: parsers: make classes mutable The parser is not read-only but has write support, so it makes more sense to have mutable classes so that API users can modify them as appopriate rather than going through hoops to clone objects in order to modify something. --- lib/python/sectracker/parsers.py | 77 ++++++++++++++++++++++-------- lib/python/sectracker_test/test_parsers.py | 2 +- 2 files changed, 59 insertions(+), 20 deletions(-) (limited to 'lib') diff --git a/lib/python/sectracker/parsers.py b/lib/python/sectracker/parsers.py index 087958cf9b..2338565548 100644 --- a/lib/python/sectracker/parsers.py +++ b/lib/python/sectracker/parsers.py @@ -17,6 +17,9 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +from dataclasses import dataclass +import typing +import traceback import re from sys import intern @@ -26,7 +29,7 @@ from collections import namedtuple as _namedtuple import sectracker.xpickle as _xpickle import sectracker.diagnostics -FORMAT = "4" +FORMAT = "5" def _sortedtuple(seq): l = list(seq) @@ -71,15 +74,41 @@ def sourcepackages(name, f): data[pkg_name] = SourcePackage(pkg_name, pkg_version, pkg_binary) return data -FlagAnnotation = _namedtuple("FlagAnnotation", "line type") -StringAnnotation = _namedtuple("StringAnnotation", - "line type description") -XrefAnnotation = _namedtuple("XrefAnnotation", "line type bugs") -PackageAnnotation = _namedtuple( - "PackageAnnotation", - "line type release package kind version description flags") -PackageBugAnnotation = _namedtuple("PackageBugAnnotation", "bug") -PackageUrgencyAnnotation = _namedtuple("PackageUrgencyAnnotation", "severity") +@dataclass +class FlagAnnotation: + line: int + type: str + +@dataclass +class StringAnnotation: + line: int + type: str + description: str + +@dataclass +class XrefAnnotation: + line: int + type: str + bugs: typing.List[str] + +@dataclass +class PackageAnnotation: + line: int + type: str + release: str + package: str + kind: str + version: str + description: str + flags: list + +@dataclass +class PackageBugAnnotation: + bug: int + +@dataclass +class PackageUrgencyAnnotation: + severity: str def _annotationdispatcher(): # Parser for inner annotations, like (bug #1345; low) @@ -174,9 +203,9 @@ def _annotationdispatcher(): @_regexpcase.rule(r'\{(.*)\}') def xref(groups, diag): - x = tuple(groups[0].strip().split()) + x = groups[0].strip().split() if x: - return XrefAnnotation(diag.line(), "xref", x) + return XrefAnnotation(line=diag.line(), type="xref", bugs=list(x)) else: diag.error("empty cross-reference") return None @@ -192,8 +221,18 @@ def _annotationdispatcher(): _annotationdispatcher = _annotationdispatcher() List = _namedtuple("List", "list messages") -Bug = _namedtuple("Bug", "file header annotations") -Header = _namedtuple("Header", "line name description") + +@dataclass +class Header: + line: int + name: str + description: str + +@dataclass +class Bug: + file: str + header: Header + annotations: list # TODO: use a list of annotations def _parselist(path, f, parseheader, finish): lineno = 0 @@ -268,7 +307,7 @@ def cvelist(path, f): return (name, desc) def finish(header, headerlineno, anns, diag): name, desc = header - return Bug(path, Header(headerlineno, name, desc), tuple(anns)) + return Bug(path, Header(headerlineno, name, desc), list(anns)) return _parselist(path, f, parseheader, finish) def writecvelist(data, f): @@ -348,7 +387,7 @@ def dsalist(path, f): def finish(header, headerlineno, anns, diag): d, m, y, name, desc = header _checkrelease(anns, diag, "DSA") - return Bug(path, Header(headerlineno, name, None), tuple(anns)) + return Bug(path, Header(headerlineno, name, None), list(anns)) return _parselist(path, f, parseheader, finish) @_xpickle.loader("DTSA" + FORMAT) @@ -365,7 +404,7 @@ def dtsalist(path, f): def finish(header, headerlineno, anns, diag): d, m, y, name, desc = header _checkrelease(anns, diag, "DTSA") - return Bug(path, Header(headerlineno, name, None), tuple(anns)) + return Bug(path, Header(headerlineno, name, None), list(anns)) return _parselist(path, f, parseheader, finish) @_xpickle.loader("DLA" + FORMAT) @@ -381,7 +420,7 @@ def dlalist(path, f): def finish(header, headerlineno, anns, diag): d, m, y, name, desc = header _checkrelease(anns, diag, "DLA") - return Bug(path, Header(headerlineno, name, None), tuple(anns)) + return Bug(path, Header(headerlineno, name, None), list(anns)) return _parselist(path, f, parseheader, finish) @_xpickle.loader("EXT" + FORMAT) @@ -397,5 +436,5 @@ def extadvlist(path, f): def finish(header, headerlineno, anns, diag): d, m, y, name, desc = header _checkrelease(anns, diag, "EXT") - return Bug(path, Header(headerlineno, name, None), tuple(anns)) + return Bug(path, Header(headerlineno, name, None), list(anns)) return _parselist(path, f, parseheader, finish) diff --git a/lib/python/sectracker_test/test_parsers.py b/lib/python/sectracker_test/test_parsers.py index 060a97ed7e..132b4e30e9 100644 --- a/lib/python/sectracker_test/test_parsers.py +++ b/lib/python/sectracker_test/test_parsers.py @@ -105,7 +105,7 @@ for (line, res, xmsgs) in [ "explanation goes here", []), ()), ('\t{CVE-2009-1234 CVE-2009-1235}', XrefAnnotation(17, "xref", - tuple("CVE-2009-1234 CVE-2009-1235".split())), + ["CVE-2009-1234", "CVE-2009-1235"]), ()), ('\t{}', None, (Message("CVE", 17, "error", "empty cross-reference"),)), -- cgit v1.2.3