Author: fw Date: 2005-10-20 10:55:10 +0000 (Thu, 20 Oct 2005) New Revision: 2497 Modified: lib/python/bugs.py lib/python/security_db.py Log: Remove support for FIXES: and FIXED-BY:. Instead, automatically copy notes from DTSA to CVE if there is a cross-reference. The copying code is updated so that it can handle conflicting annotations. If there is a conflict, the later version wins. lib/python/bugs.py (BugBase, Bug): Remove xref_fixes and xref_fixedby members. (FileBase): Remove FIXES:/FIXED-BY: regexps and corresponding code. lib/python/security_db.py (DB): Bump schema version. (DB.initSchema): Remove normalized_target and copy_notes field from the bugs_xref table. (DB.readBugs): No need to maintain the normalized_target column anymore. Update the code which copies the notes. The code is much simpler now because we do not handle recursive copies. (DB.getBugXrefs): Use target instead of normalized_target. Modified: lib/python/bugs.py ==================================================================--- lib/python/bugs.py 2005-10-20 10:08:28 UTC (rev 2496) +++ lib/python/bugs.py 2005-10-20 10:55:10 UTC (rev 2497) @@ -235,8 +235,6 @@ self.comments = comments self.notes = [] self.xref = [] - self.xref_fixes = [] - self.xref_fixedby = [] self.not_for_us = False def isFromCVE(self): @@ -309,26 +307,11 @@ raise ValueError, \ "cross reference to %s appears multiple times" % x - # We use INSERT OR REPLACE below because the copy annotations - # must override plain cross-references. - - for x in self.xref_fixes: - cursor.execute("""INSERT OR REPLACE INTO bugs_xref - (source, target, copy_notes) VALUES (?, ?, 1)""", - (self.name, x)) - - for x in self.xref_fixedby: - cursor.execute("""INSERT OR REPLACE INTO bugs_xref - (source, target, copy_notes) VALUES (?, ?, 1)""", - (x, self.name)) - # Swap x and self.name because FIXED-BY: works in the other - # direction. - class Bug(BugBase): """Class for bugs for which we have some data.""" def __init__(self, fname, lineno, date, name, description, comments, notes, - xref, xref_fixes, xref_fixedby, not_for_us=False): + xref, not_for_us=False): assert len(notes) == 0 or isinstance(notes[0], PackageNote) assert len(xref) == 0 or type(xref[0]) == types.StringType assert type(not_for_us) == types.BooleanType @@ -336,8 +319,6 @@ description, comments) self.notes = notes self.xref = xref - self.xref_fixes = xref_fixes - self.xref_fixedby = xref_fixedby self.not_for_us = not_for_us def mergeNotes(self): @@ -408,7 +389,7 @@ Bug.__init__(self, data[''source_file''], data[''source_line''], data[''release_date''], name, data[''description''], comments=[], - notes=[], xref=[], xref_fixes=[], xref_fixedby=[], + notes=[], xref=[], not_for_us=not not data[''not_for_us'']) for (x,) in cursor.execute\ (''SELECT target FROM bugs_xref WHERE source = ?'', (name,)): @@ -434,15 +415,6 @@ n.loadBugs(cursor) self.notes.append(n) - for (target,) in cursor.execute( - "SELECT target FROM bugs_xref WHERE source = ? AND copy_notes", - (name,)): - self.xref_fixes.append(target) - for (target,) in cursor.execute( - "SELECT source FROM bugs_xref WHERE target = ? AND copy_notes", - (name,)): - self.xref_fixedby.append(target) - def getDebianBugs(self, cursor): """Returns a list of Debian bugs to which the bug report refers.""" return map(lambda (x,): x, cursor.execute( @@ -498,11 +470,6 @@ re_xref_entry_own = re.compile( ''^(?:CVE-\d{4}-\d{4}|DSA-\d+(?:-\d+)?|DTSA-\d+-\d+)$'') - re_xref_fixes_required = re.compile(r''^FIXES'') - re_xref_fixes = re.compile(r''^FIXES:\s+(.*?)\s*$'') - re_xref_fixedby_required = re.compile(r''^FIXED-BY'') - re_xref_fixedby = re.compile(r''^FIXED-BY:\s+(.*?)\s*$'') - re_package_required = re.compile(r''^(?:\[.*\]\s*)?-'') re_package_version = re.compile( r''^(?:\[([a-z]+)\] )?- ([A-Za-z0-9:.+-]+)\s*'' @@ -602,8 +569,6 @@ not_for_us = None xref = [] - xref_fixes = [] - xref_fixedby = [] pkg_notes = [] comments = [] cve_reserved = False @@ -633,14 +598,6 @@ if handle_xref(self.re_xref_required, self.re_xref, self.re_xref_entry, xref): continue - if handle_xref(self.re_xref_fixes_required, - self.re_xref_fixes, - self.re_xref_entry_own, xref_fixes): - continue - if handle_xref(self.re_xref_fixedby_required, - self.re_xref_fixedby, - self.re_xref_entry_own, xref_fixedby): - continue if self.re_package_required.match(r): match = self.re_package_version.match(r) @@ -732,9 +689,7 @@ yield self.finishBug(Bug(self.file.name, first_lineno, date, record_name, description, comments, - notes=pkg_notes, xref=xref, - xref_fixes=xref_fixes, - xref_fixedby=xref_fixedby)) + notes=pkg_notes, xref=xref)) else: yield BugReservedCVE(self.file.name, first_lineno, record_name, comments) @@ -761,8 +716,6 @@ yield self.finishBug(Bug(self.file.name, first_lineno, date, record_name, description, comments, notes=[], xref=xref, - xref_fixes=xref_fixes, - xref_fixedby=xref_fixedby, not_for_us=True)) else: if not self.isUniqueName(record_name): @@ -776,9 +729,7 @@ record_name = ''FAKE-%07d-%06d'' % (first_bug, first_lineno) yield self.finishBug(Bug(self.file.name, first_lineno, date, record_name, description, - comments, notes=pkg_notes, xref=xref, - xref_fixes=xref_fixes, - xref_fixedby=xref_fixedby)) + comments, notes=pkg_notes, xref=xref)) def finishBug(self, bug): """Applies a transformation to the bug after it has been Modified: lib/python/security_db.py ==================================================================--- lib/python/security_db.py 2005-10-20 10:08:28 UTC (rev 2496) +++ lib/python/security_db.py 2005-10-20 10:55:10 UTC (rev 2497) @@ -111,7 +111,7 @@ self.db = apsw.Connection(name) self.verbose = verbose - self.schema_version = 15 + self.schema_version = 17 self._initFunctions() c = self.cursor() @@ -257,12 +257,8 @@ cursor.execute("""CREATE TABLE bugs_xref (source TEXT NOT NULL, target TEXT NOT NULL, - normalized_target TEXT NOT NULL DEFAULT '''', - copy_notes INTEGER NOT NULL DEFAULT 0, PRIMARY KEY (source, target))""") - cursor.execute( - """CREATE INDEX bugs_xref_normalized_target - ON bugs_xref(normalized_target)""") + cursor.execute("CREATE INDEX bugs_xref_target ON bugs_xref(target)") cursor.execute("""CREATE TABLE bug_status (bug_name TEXT NOT NULL, @@ -713,9 +709,6 @@ if self.verbose: print " check cross-references" - # Keep normalized_target column for now. - cursor.execute("UPDATE bugs_xref SET normalized_target = target") - for (bug,) in cursor.execute( """SELECT DISTINCT target FROM bugs_xref EXCEPT SELECT name FROM bugs"""): @@ -724,62 +717,46 @@ errors.append("reference to unknwown bug " + bug) if self.verbose: - print " apply FIXES" + print " copy notes" - target_sources = {} - for source, target in list(cursor.execute( - """SELECT source, normalized_target - FROM bugs_xref WHERE copy_notes""")): - if target_sources.has_key(target): - target_sources[target][source] = True - else: - target_sources[target] = {source : True} + # Copy notes from DTSA to CVE. - # Recursively collect all sources for each target. Add new - # sources until the set of sources stabilizes. - for sources in target_sources.values(): - while 1: - old_size = len(sources.keys()) - for src in sources.keys(): - for s in target_sources.get(src, {}).keys(): - sources[s] = True - if len(sources.keys()) == old_size: - break - - # Copy all the notes from all sources. - for (target, sources) in target_sources.items(): - sources = sources.keys() - for source in sources: + old_source = '''' + for source, target in list(cursor.execute( + """SELECT source, target FROM bugs_xref + WHERE source LIKE ''DTSA-%'' AND target LIKE ''CVE-%''""")): + if source <> old_source: source_bug = bugs.BugFromDB(cursor, source) - for n in source_bug.notes: - # Only copy "real" notes, not notes which have - # already bee ncopied. - if n.bug_origin: - continue - if n.release: - rel = str(n.release) + old_source = source + for n in source_bug.notes: + # We do not copy recursively. + assert not n.bug_origin + + if n.release: + rel = str(n.release) + else: + rel = '''' + present = False + for (version, note_id) in list(cursor.execute( + """SELECT fixed_version, id + FROM package_notes + WHERE bug_name = ? AND package = ? AND release = ?""", + (target, n.package, rel))): + if n.fixed_version > debian_support.Version(version): + # If our version is larger, it is the definitive one. + # Remove the existing entry in this case. + cursor.execute( + "DELETE FROM debian_bugs WHERE note = ?", + (note_id,)) + cursor.execute( + """DELETE FROM package_notes + WHERE bug_name = ? AND package = ? + AND release = ?""", + (target, n.package, rel)) else: - rel = '''' - present = False - for (version, origin) in list(cursor.execute( - """SELECT fixed_version, bug_origin - FROM package_notes - WHERE bug_name = ? AND package = ? AND release = ?""", - (target, n.package, rel))): - if version <> str(n.fixed_version): - bug = bugs.BugFromDB(cursor, origin or target) - errors.append( - ("%s: %d: version %s for package %s " - + "conflicts with %s") - % (bug.source_file, bug.source_line, - version, n.package, source_bug.name)) - errors.append("%s: %d: location of %s" - % (source_bug.source_file, - source_bug.source_line, - source_bug.name)) present = True - if not present: - n.writeDB(cursor, target, bug_origin=source) + if not present: + n.writeDB(cursor, target, bug_origin=source) if errors: raise InsertError(errors) @@ -1434,10 +1411,10 @@ for (bug_name,) in cursor.execute( """SELECT DISTINCT bug - FROM (SELECT normalized_target AS bug + FROM (SELECT target AS bug FROM bugs_xref WHERE source = ? UNION ALL SELECT source AS bug - FROM bugs_xref WHERE normalized_target = ? + FROM bugs_xref WHERE target = ? UNION ALL SELECT bug_origin AS bug FROM package_notes WHERE bug_name = ? AND bug_origin <> '''') WHERE bug <> ?