Author: fw Date: 2005-09-24 15:43:04 +0000 (Sat, 24 Sep 2005) New Revision: 2156 Modified: lib/python/bugs.py lib/python/security_db.py Log: Implement NOT-FOR-US:, <unfixed>, <not-affected> and <itp>. lib/python/bugs.py (PackageNote.writeDB): Store package_kind attribute in the database, so that we can detect notes for ITPs. (PackageNoteParsed.__init__): ''unfixed'' is no longer a valid tag. (FileBase): Update regular expressions. (FileBase.__iter__): Parse new "- PACKAGE <TAG>" annotations. Implement NOT-FOR-US:. Caclulate the Debian bug number for a FAKE name when it is needed. lib/python/security_db.py (DB.calculateVulnerabilities): Do not overrite "itp" values in the package_kind column of package_notes. Check that ITPed packages are not present in the archive. (DB.getITPs): New method. Modified: lib/python/bugs.py ==================================================================--- lib/python/bugs.py 2005-09-24 15:35:43 UTC (rev 2155) +++ lib/python/bugs.py 2005-09-24 15:43:04 UTC (rev 2156) @@ -144,10 +144,11 @@ else: r = '''' cursor.execute("""INSERT INTO package_notes - (bug_name, package, fixed_version, release, urgency, bug_origin) - VALUES (?, ?, ?, ?, ?, ?)""", + (bug_name, package, fixed_version, release, urgency, bug_origin, + package_kind) + VALUES (?, ?, ?, ?, ?, ?, ?)""", (bug_name, self.package, v, r, - str(self.urgency), bug_origin)) + str(self.urgency), bug_origin, self.package_kind)) for (rowid,) in cursor.execute(''SELECT last_insert_rowid()''): self.id = rowid for b in self.bugs: @@ -214,10 +215,6 @@ bugs.append(int(bug)) continue - if n == ''unfixed'': - self.unfixed = True - continue - raise SyntaxError , ''unknown package note %s\n'' % `n` PackageNote.__init__(self, package, version, release, urgency) self.bugs = bugs @@ -501,10 +498,14 @@ # temporary hack, until we know what "!" actually means. re_package_required = re.compile(r''^(?:\[.*\]\s*)?[-!]'') - re_package = re.compile(r''^(?:\[([a-z]+)\] )?[-!] ([A-Za-z0-9:.+-]+)'' - + r''(?:\s+([A-Za-z0-9:.+-]+))?\s*(?:\((.*)\))?$'') - re_not_for_us_required = re.compile(r''^NOTE:\s+not?e?-f[ou]?r-[us]'') - re_not_for_us = re.compile(r''^NOTE:\s+not-for-us(?:\s+\((.*)\))?\s*$'') + re_package_version = re.compile( + r''^(?:\[([a-z]+)\] )?[-!] ([A-Za-z0-9:.+-]+)\s*'' + + r''(?:\s([A-Za-z0-9:.+-]+)\s*)?(?:\s\((.*)\))?$'') + re_package_no_version = re.compile( + r''^(?:\[([a-z]+)\] )?[-!] ([A-Za-z0-9:.+-]+)'' + + r''\s+<([a-z-]+)>\s*(?:\s\((.*)\))?$'') + re_not_for_us_required = re.compile(r''^NOT-FOR-US:'') + re_not_for_us = re.compile(r''^NOT-FOR-US:\s+(.*?)\s*$'') re_reserved = re.compile(r''^NOTE:\s+reserved\s*$'') re_rejected = re.compile(r''^NOTE:\s+rejected\s*$'') re_note = re.compile(r''^NOTE:\s+(.*)$'') @@ -601,7 +602,6 @@ comments = [] cve_reserved = False cve_rejected = False - first_bug = 0 for (lineno, r) in record: def handle_xref(re_required, re_real, re_entry, target): @@ -637,32 +637,45 @@ continue if self.re_package_required.match(r): - match = self.re_package.match(r) + match = self.re_package_version.match(r) if match: (release, p, v, d) = match.groups() - if v is None and d is None and \ - self.no_version_needs_note: - raise SyntaxError, \ - ''version-less package entry requires note'' + pkg_notes.append( + PackageNoteParsed(p, v, d, release=release)) + continue + match = self.re_package_no_version.match(r) + if match: + (release, p, v, d) = match.groups() if v == ''not-affected'': - # ''0'' is the minimum version number possible. pkg_notes.append(PackageNoteParsed (p, ''0'', ''unimportant'', release=release)) - # ''d'' is a free-form field in this case, - # if it is present. if d: - comments.append((''NOTE'', d)) + # Not exactly idea, but we have to record the + # free-form text in some way. + if r[-1] == ''\n'': + r = r[:-1] + comments.append((''NOTE'', r)) + elif v == ''itp'': + x = PackageNoteParsed(p, None, d, release=release) + x.package_kind = ''itp'' + if not x.bugs: + self.raiseSyntaxError( + "ITP note needs Debian bug reference", + lineno) + pkg_notes.append(x) + elif v == ''unfixed'': + pkg_notes.append(PackageNoteParsed + (p, None, d, release=release)) else: - x = PackageNoteParsed(p, v, d, release=release) - pkg_notes.append(x) - if first_bug == 0 and len(x.bugs) > 0: - first_bug = x.bugs[0] - else: - self.raiseSyntaxError("expected package entry, got: " - + `r`, lineno) - continue + self.raiseSyntaxError( + "invalid special version %s in package entry" + % `r`, lineno) + continue + + self.raiseSyntaxError( + "expected package entry, got: " + `r`, lineno) if self.re_not_for_us_required.match(r): match = self.re_not_for_us.match(r) @@ -672,7 +685,7 @@ not_for_us = '''' continue else: - self.raiseSyntaxError("expected not-for-us entry, " + self.raiseSyntaxError("expected NOT-FOR-US entry, " + "got: " + `r`, lineno) match = self.re_reserved.match(r) @@ -747,6 +760,13 @@ not_for_us=True)) else: if not self.isUniqueName(record_name): + first_bug = 0 + for n in pkg_notes: + for b in n.bugs: + first_bug = b + break + if first_bug: + break record_name = ''FAKE-%07d-%06d'' % (first_bug, first_lineno) yield self.finishBug(Bug(self.file.name, first_lineno, date, record_name, description, Modified: lib/python/security_db.py ==================================================================--- lib/python/security_db.py 2005-09-24 15:35:43 UTC (rev 2155) +++ lib/python/security_db.py 2005-09-24 15:43:04 UTC (rev 2156) @@ -910,11 +910,14 @@ if self.verbose: print " checking source/binary packages" - cursor.execute("UPDATE package_notes SET package_kind = ''unknown''") cursor.execute( + """UPDATE package_notes SET package_kind = ''unknown'' + WHERE package_kind IN (''source'', ''binary'')""") + cursor.execute( """UPDATE package_notes SET package_kind = ''source'' - WHERE EXISTS (SELECT * FROM source_packages AS p - WHERE p.name = package_notes.package)""") + WHERE package_kind = ''unknown'' + AND EXISTS (SELECT * FROM source_packages AS p + WHERE p.name = package_notes.package)""") cursor.execute( """UPDATE package_notes SET package_kind = ''binary'' WHERE package_kind = ''unknown'' @@ -949,6 +952,18 @@ result.append("%s:%d: candidates are %s and %s" % (b.source_file, b.source_line, s1, s2)) + for (bug_name, package) in list(cursor.execute( + """SELECT n.bug_name, n.package + FROM package_notes AS n + WHERE n.package_kind = ''itp'' + AND ((EXISTS (SELECT * FROM source_packages + WHERE name = n.package)) + OR (EXISTS (SELECT * FROM binary_packages + WHERE name = n.package)))""")): + b = bugs.BugFromDB(cursor, bug_name) + result.append("%s:%d: ITPed package %s is in the archive" + % (b.source_file, b.source_line, package)) + if False: # The following check looks useful, but there are # situations where we want to be very explicit about @@ -1432,6 +1447,22 @@ if old_package: yield (old_package, bugs) + def getITPs(self, cursor): + """Returns a generator for a list of unknown packages. + Each entry has the form (PACKAGE, BUG-LIST, DEBIAN-BUG-LIST).""" + + # The "|| ''''" is required to convert the string_set argument + # to a string. + for (package, bugs, debian_bugs) in cursor.execute( + """SELECT DISTINCT n.package, string_set(n.bug_name), + string_set(db.bug || '''') + FROM package_notes AS n, debian_bugs AS db + WHERE package_kind = ''itp'' + AND db.note = n.id + GROUP BY n.package + ORDER BY n.package"""): + yield (package, bugs.split('',''), map(int, debian_bugs.split('',''))) + def check(self, cursor=None): """Runs a simple consistency check and prints the results."""