[Git][security-tracker-team/security-tracker][helmutg/parallel-web] 2 commits: bin/tracker_service.py: open the database connection for each request
Helmut Grohne (@helmutg)
helmutg at debian.org
Mon Aug 24 12:29:43 BST 2026
Helmut Grohne pushed to branch helmutg/parallel-web at Debian Security Tracker / security-tracker
Commits:
4a4f1de0 by Helmut Grohne at 2026-08-24T13:07:47+02:00
bin/tracker_service.py: open the database connection for each request
Until now, there was one apsw (sqlite3) connection for the
TrackerService. It would be servicing requests from multiple threads,
but rendering the page would access the same database connection object.
With this change, each request handler call opens its own database
connection as needed. The TrackerService object no longer has a
connection and therefore can survive threading, forking and asynchronous
serving without issues.
Note that concurrently creating database connections no longer is a
problem as possible database migrations are not attempted when opening
read-only. Race conditions while opening are thus eliminated.
While opening a connection may seem like a heavy operation, for sqlite3
it really isn't.
- - - - -
5eea0a77 by Helmut Grohne at 2026-08-24T13:07:47+02:00
WebServiceHTTPAdapter: allow parallel request processing
Until now, the page rendering handlers were fully sequentialized via a
threading.Lock. This was necessary as the TrackerService had a single
apsw.Connection object used by all handlers. The use of a single
connection required mutual exclusion. Until f1fa755e8217 ("precompute
/data/json and store it in side security.db"), the TrackerService object
also carried a cached version of /data/json as an attribute. Both are
gone now and I also asked Florian Weimer about the lock. In the end, we
agreed that it can go away once the database connection is no longer
shared.
- - - - -
3 changed files:
- bin/tracker_service.py
- lib/python/security_db.py
- lib/python/web_support.py
Changes:
=====================================
bin/tracker_service.py
=====================================
@@ -110,7 +110,7 @@ class TrackerService(WebServiceBase):
def __init__(self, db_name):
WebServiceBase.__init__(self)
- self.db = security_db.DB(db_name, readonly=True)
+ self.db_name = db_name
self.stable_releases = config.get_supported_releases()
self.stable_releases.remove(config.get_release_codename('testing'))
@@ -156,6 +156,10 @@ class TrackerService(WebServiceBase):
self.register('distributions.json', self.page_distributions_json)
self.register('script.js', self.page_script_js)
+ def open_db(self):
+ return security_db.DB(self.db_name, readonly=True)
+
+
def page_style_css(self, path, params, url):
with open('../static/style.css', 'rb') as f:
content=f.read()
@@ -271,8 +275,6 @@ data source.""")],
return self.page_object_or_redirect(url, obj, True)
def page_object_or_redirect(self, url, obj, redirect):
- c = self.db.cursor()
-
if not obj:
# Redirect to start page.
return RedirectResult(url.scriptRelativeFull(""))
@@ -289,30 +291,34 @@ data source.""")],
bugnumber = int(obj)
except ValueError:
pass
- if bugnumber:
- buglist = list(self.db.getBugsFromDebianBug(c, bugnumber))
- if buglist:
- return self.page_debian_bug(url, bugnumber, buglist, fake_bug)
- if redirect:
- return RedirectResult(self.url_debian_bug(url, str(bugnumber)),
- permanent=False)
- if 'A' <= obj[0] <= 'Z':
- # Bug names start with a capital letter.
- return self.page_bug(url, obj, redirect)
+ with self.open_db() as db:
+ c = db.cursor()
+
+ if bugnumber:
+ buglist = list(db.getBugsFromDebianBug(c, bugnumber))
+ if buglist:
+ return self.page_debian_bug(url, bugnumber, buglist, fake_bug)
+ if redirect:
+ return RedirectResult(self.url_debian_bug(url, str(bugnumber)),
+ permanent=False)
+
+ if 'A' <= obj[0] <= 'Z':
+ # Bug names start with a capital letter.
+ return self.page_bug(db, url, obj, redirect)
- if self.db.isSourcePackage(c, obj):
- return RedirectResult(self.url_source_package(url, obj, full=True))
+ if db.isSourcePackage(c, obj):
+ return RedirectResult(self.url_source_package(url, obj, full=True))
return self.page_not_found(url, obj)
- def page_bug(self, url, name, redirect):
+ def page_bug(self, db, url, name, redirect):
# FIXME: Normalize CAN-* to CVE-* when redirecting. Too many
# people still use CAN.
if redirect and name[0:4] == 'CAN-':
name = 'CVE-' + name[4:]
- cursor = self.db.cursor()
+ cursor = db.cursor()
try:
bug = bugs.BugFromDB(cursor, name)
except ValueError:
@@ -330,7 +336,7 @@ data source.""")],
def gen_header():
yield B("Name"), bug.name
- nvd = self.db.getNVD(cursor, bug.name)
+ nvd = db.getNVD(cursor, bug.name)
if nvd and nvd.cve_desc:
yield B("Description"), nvd.cve_desc
@@ -392,7 +398,7 @@ data source.""")],
if source_xref:
yield B("Source"), source_xref
- xref = list(self.db.getBugXrefs(cursor, bug.name))
+ xref = list(db.getBugXrefs(cursor, bug.name))
if xref:
yield B("References"), self.make_xref_list(url, xref)
@@ -417,7 +423,7 @@ data source.""")],
def gen_source():
old_pkg = ''
for (package, release, version, vulnerable) \
- in self.db.getSourcePackages(cursor, bug.name):
+ in db.getSourcePackages(cursor, bug.name):
if package == old_pkg:
package = ''
else:
@@ -583,258 +589,262 @@ to improve our documentation and procedures, so feedback is welcome.""")])])
pkg = path[0]
- if not self.db.isSourcePackage(self.db.cursor(), pkg):
- return self.page_not_found(url, pkg)
-
- data = security_db.getBugsForSourcePackage(self.db.cursor(), pkg)
-
- def gen_versions():
- for (release, version) in self.db.getSourcePackageVersions(
- self.db.cursor(), pkg):
- yield release, version
- def gen_bug_list(lst):
- for bug in lst:
- yield self.make_xref(url, bug.bug), bug.description
-
- def format_summary_entry(per_release):
- if per_release is None:
- return self.make_purple('unknown')
- if per_release.vulnerable == security_db.Vulnerable.AFFECTED:
- if per_release.state == 'no-dsa':
- if per_release.reason:
- text = 'vulnerable (no DSA, %s)' % per_release.reason
+ with self.open_db() as db:
+ if not db.isSourcePackage(db.cursor(), pkg):
+ return self.page_not_found(url, pkg)
+
+ data = security_db.getBugsForSourcePackage(db.cursor(), pkg)
+
+ def gen_versions():
+ for (release, version) in db.getSourcePackageVersions(
+ db.cursor(), pkg):
+ yield release, version
+ def gen_bug_list(lst):
+ for bug in lst:
+ yield self.make_xref(url, bug.bug), bug.description
+
+ def format_summary_entry(per_release):
+ if per_release is None:
+ return self.make_purple('unknown')
+ if per_release.vulnerable == security_db.Vulnerable.AFFECTED:
+ if per_release.state == 'no-dsa':
+ if per_release.reason:
+ text = 'vulnerable (no DSA, %s)' % per_release.reason
+ else:
+ text = 'vulnerable (no DSA)'
+ hint = per_release.comment
+ return self.make_mouseover((self.make_yellow(text),),
+ text=hint)
else:
- text = 'vulnerable (no DSA)'
- hint = per_release.comment
- return self.make_mouseover((self.make_yellow(text),),
- text=hint)
- else:
- return self.make_red('vulnerable')
- if per_release.vulnerable == security_db.Vulnerable.UNDETERMINED:
- return self.make_purple('undetermined')
- assert per_release.vulnerable == security_db.Vulnerable.FIXED
- return self.make_green('fixed')
-
- def gen_summary(bugs):
- for bug in bugs:
- status_row = tuple(
- format_summary_entry(bug.releases.get(rel, None))
- for rel in data.all_releases)
- yield (self.make_xref(url, bug.bug),) + status_row \
- + (bug.description,)
+ return self.make_red('vulnerable')
+ if per_release.vulnerable == security_db.Vulnerable.UNDETERMINED:
+ return self.make_purple('undetermined')
+ assert per_release.vulnerable == security_db.Vulnerable.FIXED
+ return self.make_green('fixed')
+
+ def gen_summary(bugs):
+ for bug in bugs:
+ status_row = tuple(
+ format_summary_entry(bug.releases.get(rel, None))
+ for rel in data.all_releases)
+ yield (self.make_xref(url, bug.bug),) + status_row \
+ + (bug.description,)
- return self.create_page(
- url, 'Information on source package ' + pkg,
- [make_menu(lambda x: x,
- (self.url_pts(url, pkg),
- pkg + ' in the Package Tracking System'),
- (self.url_debian_bug_pkg(url, pkg),
- pkg + ' in the Bug Tracking System'),
- (self.url_source_code(url, pkg),
- pkg + ' source code'),
- (self.url_testing_status(url, pkg),
- pkg + ' in the testing migration checker')),
- make_table(gen_versions(), title=H2('Available versions'), caption=('Release', 'Version')),
-
- make_table(
- gen_summary(data.open),
- title=H2('Open issues'),
- caption=('Bug',) + data.all_releases + ('Description',),
- replacement='No known open issues.'
- ),
-
-
- make_table(
- gen_summary(data.unimportant),
- title=H2('Open unimportant issues'),
- caption=('Bug',) + data.all_releases + ('Description',),
- replacement='No known unimportant issues.'
- ),
-
- make_table(gen_bug_list(data.resolved),
- title=H2('Resolved issues'),
- caption=('Bug', 'Description'),
- replacement='No known resolved issues.'),
-
- make_table(gen_bug_list(self.db.getDSAsForSourcePackage
- (self.db.cursor(), pkg)),
- title=H2('Security announcements'),
- caption=('DSA / DLA', 'Description'),
- replacement='No known security announcements.')
- ])
+ return self.create_page(
+ url, 'Information on source package ' + pkg,
+ [make_menu(lambda x: x,
+ (self.url_pts(url, pkg),
+ pkg + ' in the Package Tracking System'),
+ (self.url_debian_bug_pkg(url, pkg),
+ pkg + ' in the Bug Tracking System'),
+ (self.url_source_code(url, pkg),
+ pkg + ' source code'),
+ (self.url_testing_status(url, pkg),
+ pkg + ' in the testing migration checker')),
+ make_table(gen_versions(), title=H2('Available versions'), caption=('Release', 'Version')),
+
+ make_table(
+ gen_summary(data.open),
+ title=H2('Open issues'),
+ caption=('Bug',) + data.all_releases + ('Description',),
+ replacement='No known open issues.'
+ ),
+
+
+ make_table(
+ gen_summary(data.unimportant),
+ title=H2('Open unimportant issues'),
+ caption=('Bug',) + data.all_releases + ('Description',),
+ replacement='No known unimportant issues.'
+ ),
+
+ make_table(gen_bug_list(data.resolved),
+ title=H2('Resolved issues'),
+ caption=('Bug', 'Description'),
+ replacement='No known resolved issues.'),
+
+ make_table(gen_bug_list(db.getDSAsForSourcePackage
+ (db.cursor(), pkg)),
+ title=H2('Security announcements'),
+ caption=('DSA / DLA', 'Description'),
+ replacement='No known security announcements.')
+ ])
def page_status_release_stable_like(self, path, params, url):
release = os.path.basename(url.path_info)
bf = BugFilter(params)
- def gen():
- old_pkg_name = ''
- for (pkg_name, bug_name, archive, urgency, vulnerable, remote, no_dsa, no_dsa_reason) in \
- self.db.cursor().execute(
- """SELECT package, bug, section, urgency, vulnerable, remote, no_dsa, no_dsa_reason
- FROM %s_status
- WHERE (bug LIKE 'CVE-%%' OR bug LIKE 'TEMP-%%')
- ORDER BY package, bug COLLATE version""" % release):
- if bf.urgencyFiltered(urgency, vulnerable):
- continue
- if bf.remoteFiltered(remote):
- continue
- if bf.nodsaFiltered(no_dsa):
- continue
- if bf.ignoredFiltered(no_dsa_reason):
- continue
- if bf.postponedFiltered(no_dsa_reason):
- continue
-
- if pkg_name == old_pkg_name:
- pkg_name = ''
- title = None
- else:
- old_pkg_name = pkg_name
- title = None
- if archive != 'main':
- title = "%s (%s)" % (pkg_name, archive)
-
- if remote is None:
- remote = '?'
- elif remote:
- remote = 'yes'
- else:
- remote = 'no'
-
- if urgency.startswith('high'):
- urgency = self.make_red(urgency)
- elif vulnerable == security_db.Vulnerable.UNDETERMINED:
- urgency = self.make_purple(urgency)
- else:
- if no_dsa:
- urgency = urgency + '*'
-
- yield self.make_source_package_ref(url, pkg_name, title), self.make_xref(url, bug_name), urgency, remote
+ with self.open_db() as db:
+ def gen():
+ old_pkg_name = ''
+ for (pkg_name, bug_name, archive, urgency, vulnerable, remote, no_dsa, no_dsa_reason) in \
+ db.cursor().execute(
+ """SELECT package, bug, section, urgency, vulnerable, remote, no_dsa, no_dsa_reason
+ FROM %s_status
+ WHERE (bug LIKE 'CVE-%%' OR bug LIKE 'TEMP-%%')
+ ORDER BY package, bug COLLATE version""" % release):
+ if bf.urgencyFiltered(urgency, vulnerable):
+ continue
+ if bf.remoteFiltered(remote):
+ continue
+ if bf.nodsaFiltered(no_dsa):
+ continue
+ if bf.ignoredFiltered(no_dsa_reason):
+ continue
+ if bf.postponedFiltered(no_dsa_reason):
+ continue
+
+ if pkg_name == old_pkg_name:
+ pkg_name = ''
+ title = None
+ else:
+ old_pkg_name = pkg_name
+ title = None
+ if archive != 'main':
+ title = "%s (%s)" % (pkg_name, archive)
+
+ if remote is None:
+ remote = '?'
+ elif remote:
+ remote = 'yes'
+ else:
+ remote = 'no'
- return self.create_page(
- url, 'Vulnerable source packages in the %s suite' % release,
- [bf.actions(url), BR(),
- make_table(gen(), caption=("Package", "Bug", "Urgency", "Remote")),
- P('''If a "*" is included in the urgency field, no DSA is planned
- for this vulnerability.'''),
- self.nvd_text])
+ if urgency.startswith('high'):
+ urgency = self.make_red(urgency)
+ elif vulnerable == security_db.Vulnerable.UNDETERMINED:
+ urgency = self.make_purple(urgency)
+ else:
+ if no_dsa:
+ urgency = urgency + '*'
+
+ yield self.make_source_package_ref(url, pkg_name, title), self.make_xref(url, bug_name), urgency, remote
+
+ return self.create_page(
+ url, 'Vulnerable source packages in the %s suite' % release,
+ [bf.actions(url), BR(),
+ make_table(gen(), caption=("Package", "Bug", "Urgency", "Remote")),
+ P('''If a "*" is included in the urgency field, no DSA is planned
+ for this vulnerability.'''),
+ self.nvd_text])
def page_status_release_testing(self, path, params, url):
bf = BugFilter(params)
- def gen():
- old_pkg_name = ''
- for (pkg_name, bug_name, archive, urgency, vulnerable,
- sid_vulnerable, ts_fixed, remote, no_dsa) \
- in self.db.cursor().execute(
- """SELECT package, bug, section, urgency, vulnerable,
- unstable_vulnerable, testing_security_fixed, remote, no_dsa
- FROM testing_status
- ORDER BY package, bug COLLATE version"""):
- if bf.urgencyFiltered(urgency, vulnerable):
- continue
- if bf.remoteFiltered(remote):
- continue
- if bf.nodsaFiltered(no_dsa):
- continue
-
- if pkg_name == old_pkg_name:
- pkg_name = ''
- title = None
- else:
- old_pkg_name = pkg_name
- title = None
- if archive != 'main':
- title = "%s (%s)" % (pkg_name, archive)
-
- if remote is None:
- remote = '?'
- elif remote:
- remote = 'yes'
- else:
- remote = 'no'
-
- if ts_fixed:
- status = 'fixed in testing-security'
- else:
- if sid_vulnerable:
- status = self.make_red('unstable is vulnerable')
+ with self.open_db() as db:
+ def gen():
+ old_pkg_name = ''
+ for (pkg_name, bug_name, archive, urgency, vulnerable,
+ sid_vulnerable, ts_fixed, remote, no_dsa) \
+ in db.cursor().execute(
+ """SELECT package, bug, section, urgency, vulnerable,
+ unstable_vulnerable, testing_security_fixed, remote, no_dsa
+ FROM testing_status
+ ORDER BY package, bug COLLATE version"""):
+ if bf.urgencyFiltered(urgency, vulnerable):
+ continue
+ if bf.remoteFiltered(remote):
+ continue
+ if bf.nodsaFiltered(no_dsa):
+ continue
+
+ if pkg_name == old_pkg_name:
+ pkg_name = ''
+ title = None
+ else:
+ old_pkg_name = pkg_name
+ title = None
+ if archive != 'main':
+ title = "%s (%s)" % (pkg_name, archive)
+
+ if remote is None:
+ remote = '?'
+ elif remote:
+ remote = 'yes'
+ else:
+ remote = 'no'
+
+ if ts_fixed:
+ status = 'fixed in testing-security'
else:
- status = self.make_dangerous('fixed in unstable')
+ if sid_vulnerable:
+ status = self.make_red('unstable is vulnerable')
+ else:
+ status = self.make_dangerous('fixed in unstable')
- if urgency.startswith('high'):
- urgency = self.make_red(urgency)
- elif vulnerable == security_db.Vulnerable.UNDETERMINED:
- urgency = self.make_purple(urgency)
+ if urgency.startswith('high'):
+ urgency = self.make_red(urgency)
+ elif vulnerable == security_db.Vulnerable.UNDETERMINED:
+ urgency = self.make_purple(urgency)
- yield (self.make_source_package_ref(url, pkg_name, title), self.make_xref(url, bug_name),
- urgency, remote, status)
+ yield (self.make_source_package_ref(url, pkg_name, title), self.make_xref(url, bug_name),
+ urgency, remote, status)
- return self.create_page(
- url, 'Vulnerable source packages in the testing suite',
- [make_menu(url.scriptRelative,
- ("status/dtsa-candidates", "Candidates for DTSAs")),
- bf.actions(url), BR(),
- make_table(gen(), caption=("Package", "Bug", "Urgency", "Remote", 'Status')),
- self.nvd_text])
+ return self.create_page(
+ url, 'Vulnerable source packages in the testing suite',
+ [make_menu(url.scriptRelative,
+ ("status/dtsa-candidates", "Candidates for DTSAs")),
+ bf.actions(url), BR(),
+ make_table(gen(), caption=("Package", "Bug", "Urgency", "Remote", 'Status')),
+ self.nvd_text])
def page_status_release_unstable_like(self, path, params, url,
rel, title, subrel=""):
bf = BugFilter(params,nonodsa=True,noignored=True,nopostponed=True)
- def gen():
- old_pkg_name = ''
- for (pkg_name, bug_name, section, urgency, vulnerable, remote) \
- in self.db.cursor().execute(
- """SELECT DISTINCT sp.name, st.bug_name,
- sp.archive, st.urgency, st.vulnerable,
- (SELECT range_remote FROM nvd_data
- WHERE cve_name = st.bug_name)
- FROM source_package_status AS st, source_packages AS sp
- WHERE st.vulnerable != ? AND sp.rowid = st.package
- AND sp.release = ? AND sp.subrelease = ''
- ORDER BY sp.name, st.bug_name COLLATE version""",
- (security_db.Vulnerable.FIXED, rel,)):
- if bf.urgencyFiltered(urgency, vulnerable):
- continue
- if bf.remoteFiltered(remote):
- continue
-
- if pkg_name == old_pkg_name:
- pkg_name = ''
- title = None
- else:
- old_pkg_name = pkg_name
- title = None
- if section != 'main':
- title = "%s (%s)" % (pkg_name, section)
-
- if remote is None:
- remote = '?'
- elif remote:
- remote = 'yes'
- else:
- remote = 'no'
-
- if urgency.startswith('high'):
- urgency = self.make_red(urgency)
- elif vulnerable == security_db.Vulnerable.UNDETERMINED:
- urgency = self.make_purple(urgency)
-
- yield self.make_source_package_ref(url, pkg_name, title), self.make_xref(url, bug_name), urgency, remote
+ with self.open_db() as db:
+ def gen():
+ old_pkg_name = ''
+ for (pkg_name, bug_name, section, urgency, vulnerable, remote) \
+ in db.cursor().execute(
+ """SELECT DISTINCT sp.name, st.bug_name,
+ sp.archive, st.urgency, st.vulnerable,
+ (SELECT range_remote FROM nvd_data
+ WHERE cve_name = st.bug_name)
+ FROM source_package_status AS st, source_packages AS sp
+ WHERE st.vulnerable != ? AND sp.rowid = st.package
+ AND sp.release = ? AND sp.subrelease = ''
+ ORDER BY sp.name, st.bug_name COLLATE version""",
+ (security_db.Vulnerable.FIXED, rel,)):
+ if bf.urgencyFiltered(urgency, vulnerable):
+ continue
+ if bf.remoteFiltered(remote):
+ continue
+
+ if pkg_name == old_pkg_name:
+ pkg_name = ''
+ title = None
+ else:
+ old_pkg_name = pkg_name
+ title = None
+ if section != 'main':
+ title = "%s (%s)" % (pkg_name, section)
+
+ if remote is None:
+ remote = '?'
+ elif remote:
+ remote = 'yes'
+ else:
+ remote = 'no'
- return self.create_page(
- url, title,
- [P("""Note that the list below is based on source packages.
- This means that packages are not listed here once a new,
- fixed source version has been uploaded to the archive, even
- if there are still some vulnerable binary packages present
- in the archive."""),
- bf.actions(url), BR(),
- make_table(gen(), caption=('Package', 'Bug', 'Urgency', 'Remote')),
- self.nvd_text])
+ if urgency.startswith('high'):
+ urgency = self.make_red(urgency)
+ elif vulnerable == security_db.Vulnerable.UNDETERMINED:
+ urgency = self.make_purple(urgency)
+
+ yield self.make_source_package_ref(url, pkg_name, title), self.make_xref(url, bug_name), urgency, remote
+
+ return self.create_page(
+ url, title,
+ [P("""Note that the list below is based on source packages.
+ This means that packages are not listed here once a new,
+ fixed source version has been uploaded to the archive, even
+ if there are still some vulnerable binary packages present
+ in the archive."""),
+ bf.actions(url), BR(),
+ make_table(gen(), caption=('Package', 'Bug', 'Urgency', 'Remote')),
+ self.nvd_text])
def page_status_release_unstable(self, path, params, url):
return self.page_status_release_unstable_like(
@@ -854,77 +864,78 @@ to improve our documentation and procedures, so feedback is welcome.""")])])
def page_status_dtsa_candidates(self, path, params, url):
bf = BugFilter(params,nonodsa=True,noignored=True,nopostponed=True)
- def gen():
- old_pkg_name = ''
- for (pkg_name, bug_name, archive, urgency, vulnerable,
- stable_later, remote) \
- in self.db.cursor().execute(
- """SELECT package, bug, section, urgency, vulnerable,
- (SELECT testing.version_id < stable.version_id
- FROM source_packages AS testing, source_packages AS stable
- WHERE testing.name = testing_status.package
- AND testing.release = ?
- AND testing.subrelease = ''
- AND testing.archive = testing_status.section
- AND stable.name = testing_status.package
- AND stable.release = ?
- AND stable.subrelease = 'security'
- AND stable.archive = testing_status.section),
- (SELECT range_remote FROM nvd_data
- WHERE cve_name = bug)
- FROM testing_status
- WHERE (NOT unstable_vulnerable)
- AND (NOT testing_security_fixed)""",
- (config.get_release_codename('testing'), config.get_release_codename('stable'))):
- if bf.urgencyFiltered(urgency, vulnerable):
- continue
- if bf.remoteFiltered(remote):
- continue
-
- if pkg_name == old_pkg_name:
- pkg_name = ''
- migration = ''
- title = None
- else:
- old_pkg_name = pkg_name
- title = None
- migration = A(self.url_testing_status(url, pkg_name),
- "check")
- if archive != 'main':
- title = "%s (%s)" % (pkg_name, archive)
-
- if remote is None:
- remote = '?'
- elif remote:
- remote = 'yes'
- else:
- remote = 'no'
-
- if urgency.startswith('high'):
- urgency = self.make_red(urgency)
- elif vulnerable == security_db.Vulnerable.UNDETERMINED:
- urgency = self.make_purple(urgency)
-
- if stable_later:
- notes = "(fixed in stable?)"
- else:
- notes = ''
-
- yield (self.make_source_package_ref(url, pkg_name, title), migration, self.make_xref(url, bug_name),
- urgency, remote, notes)
+ with self.open_db() as db:
+ def gen():
+ old_pkg_name = ''
+ for (pkg_name, bug_name, archive, urgency, vulnerable,
+ stable_later, remote) \
+ in db.cursor().execute(
+ """SELECT package, bug, section, urgency, vulnerable,
+ (SELECT testing.version_id < stable.version_id
+ FROM source_packages AS testing, source_packages AS stable
+ WHERE testing.name = testing_status.package
+ AND testing.release = ?
+ AND testing.subrelease = ''
+ AND testing.archive = testing_status.section
+ AND stable.name = testing_status.package
+ AND stable.release = ?
+ AND stable.subrelease = 'security'
+ AND stable.archive = testing_status.section),
+ (SELECT range_remote FROM nvd_data
+ WHERE cve_name = bug)
+ FROM testing_status
+ WHERE (NOT unstable_vulnerable)
+ AND (NOT testing_security_fixed)""",
+ (config.get_release_codename('testing'), config.get_release_codename('stable'))):
+ if bf.urgencyFiltered(urgency, vulnerable):
+ continue
+ if bf.remoteFiltered(remote):
+ continue
+
+ if pkg_name == old_pkg_name:
+ pkg_name = ''
+ migration = ''
+ title = None
+ else:
+ old_pkg_name = pkg_name
+ title = None
+ migration = A(self.url_testing_status(url, pkg_name),
+ "check")
+ if archive != 'main':
+ title = "%s (%s)" % (pkg_name, archive)
+
+ if remote is None:
+ remote = '?'
+ elif remote:
+ remote = 'yes'
+ else:
+ remote = 'no'
- return self.create_page(
- url, "Candidates for DTSAs",
- [P("""The table below lists packages which are fixed
-in unstable, but unfixed in testing. Use the testing migration
-checker to find out why they have not entered testing yet."""),
- make_menu(url.scriptRelative,
- ("status/release/testing",
- "List of vulnerable packages in testing")),
- bf.actions(url), BR(),
- make_table(gen(),
- caption=("Package", "Migration", "Bug", "Urgency",
- "Remote", ""))])
+ if urgency.startswith('high'):
+ urgency = self.make_red(urgency)
+ elif vulnerable == security_db.Vulnerable.UNDETERMINED:
+ urgency = self.make_purple(urgency)
+
+ if stable_later:
+ notes = "(fixed in stable?)"
+ else:
+ notes = ''
+
+ yield (self.make_source_package_ref(url, pkg_name, title), migration, self.make_xref(url, bug_name),
+ urgency, remote, notes)
+
+ return self.create_page(
+ url, "Candidates for DTSAs",
+ [P("""The table below lists packages which are fixed
+ in unstable, but unfixed in testing. Use the testing migration
+ checker to find out why they have not entered testing yet."""),
+ make_menu(url.scriptRelative,
+ ("status/release/testing",
+ "List of vulnerable packages in testing")),
+ bf.actions(url), BR(),
+ make_table(gen(),
+ caption=("Package", "Migration", "Bug", "Urgency",
+ "Remote", ""))])
def page_status_todo(self, path, params, url):
hide_check = bool(params.get('hide_check', False))
@@ -935,116 +946,120 @@ checker to find out why they have not entered testing yet."""),
flags = A(url.updateParamsDict({'hide_check' : '1'}),
'Hide "check" TODOs')
- def gen():
- for (bug, description, note) in self.db.getTODOs(hide_check=hide_check):
- yield self.make_xref(url, bug), description, note
- return self.create_page(
- url, 'Bugs with TODO items',
- [P(flags), make_table(gen(), caption=('Bug', 'Description', 'Note'))])
+ with self.open_db() as db:
+ def gen():
+ for (bug, description, note) in db.getTODOs(hide_check=hide_check):
+ yield self.make_xref(url, bug), description, note
+ return self.create_page(
+ url, 'Bugs with TODO items',
+ [P(flags), make_table(gen(), caption=('Bug', 'Description', 'Note'))])
def page_status_undetermined(self, path, params, url):
- def gen():
- outrel = []
- old_bug = ''
- old_pkg = ''
- old_dsc = ''
- last_displayed = ''
- releases = config.get_supported_releases()
- for (pkg_name, bug_name, release, desc) in self.db.cursor().execute(
- """SELECT DISTINCT sp.name, st.bug_name, sp.release,
- bugs.description
- FROM source_package_status AS st, source_packages AS sp, bugs
- WHERE st.vulnerable == ? AND sp.rowid = st.package
- AND sp.release IN (""" + ",".join("?" * len(releases)) + """)
- AND sp.subrelease = '' AND st.bug_name == bugs.name
- ORDER BY sp.name, st.bug_name COLLATE version""",
- (security_db.Vulnerable.UNDETERMINED, *releases)):
-
- if old_bug == '':
- old_bug = bug_name
- old_pkg = pkg_name
- old_dsc = desc
- elif old_bug != bug_name:
- if old_pkg == last_displayed:
- to_display = ''
- else:
- to_display = old_pkg
- yield to_display, self.make_xref(url, old_bug), old_dsc, ', '.join(outrel)
- last_displayed = old_pkg
- old_bug = bug_name
- old_pkg = pkg_name
- old_dsc = desc
- outrel = []
- outrel.append( release )
- yield old_pkg, self.make_xref(url, old_bug), old_dsc, ', '.join(outrel)
-
- return self.create_page(url, 'Packages that may be vulnerable but need to be checked (undetermined issues)',
- [P("""This page lists packages that may or may not be affected
- by known issues. This means that some additional work needs to
- be done to determined whether the package is actually
- vulnerable or not. This list is a good area for new
- contributors to make quick and meaningful contributions."""),
- make_table(gen(), caption=('Package', 'Bug', 'Description', 'Releases'))])
+ with self.open_db() as db:
+ def gen():
+ outrel = []
+ old_bug = ''
+ old_pkg = ''
+ old_dsc = ''
+ last_displayed = ''
+ releases = config.get_supported_releases()
+ for (pkg_name, bug_name, release, desc) in db.cursor().execute(
+ """SELECT DISTINCT sp.name, st.bug_name, sp.release,
+ bugs.description
+ FROM source_package_status AS st, source_packages AS sp, bugs
+ WHERE st.vulnerable == ? AND sp.rowid = st.package
+ AND sp.release IN (""" + ",".join("?" * len(releases)) + """)
+ AND sp.subrelease = '' AND st.bug_name == bugs.name
+ ORDER BY sp.name, st.bug_name COLLATE version""",
+ (security_db.Vulnerable.UNDETERMINED, *releases)):
+
+ if old_bug == '':
+ old_bug = bug_name
+ old_pkg = pkg_name
+ old_dsc = desc
+ elif old_bug != bug_name:
+ if old_pkg == last_displayed:
+ to_display = ''
+ else:
+ to_display = old_pkg
+ yield to_display, self.make_xref(url, old_bug), old_dsc, ', '.join(outrel)
+ last_displayed = old_pkg
+ old_bug = bug_name
+ old_pkg = pkg_name
+ old_dsc = desc
+ outrel = []
+ outrel.append( release )
+ yield old_pkg, self.make_xref(url, old_bug), old_dsc, ', '.join(outrel)
+
+ return self.create_page(url, 'Packages that may be vulnerable but need to be checked (undetermined issues)',
+ [P("""This page lists packages that may or may not be affected
+ by known issues. This means that some additional work needs to
+ be done to determined whether the package is actually
+ vulnerable or not. This list is a good area for new
+ contributors to make quick and meaningful contributions."""),
+ make_table(gen(), caption=('Package', 'Bug', 'Description', 'Releases'))])
def page_status_unimportant(self, path, params, url):
- def gen():
- outrel = []
- old_bug = ''
- old_pkg = ''
- old_dsc = ''
- old_name = ''
- last_displayed = ''
- releases = config.get_supported_releases()
- for (pkg_name, bug_name, release, desc) in self.db.cursor().execute(
- """SELECT DISTINCT sp.name, st.bug_name, sp.release,
- bugs.description
- FROM source_package_status AS st, source_packages AS sp, bugs
- WHERE st.vulnerable != ? AND sp.rowid = st.package
- AND sp.release IN (""" + ",".join("?" * len(releases)) + """)
- AND st.urgency == 'unimportant'
- AND sp.subrelease = '' AND st.bug_name == bugs.name
- ORDER BY sp.name, st.bug_name COLLATE version""",
- (security_db.Vulnerable.FIXED, *releases)):
-
- if old_bug == '':
- old_bug = bug_name
- old_pkg = pkg_name
- old_dsc = desc
- elif old_bug != bug_name:
- if old_pkg == last_displayed:
- to_display = ''
- else:
- to_display = old_pkg
- yield to_display, self.make_xref(url, old_bug), old_dsc, ', '.join(outrel)
- last_displayed = old_pkg
- old_bug = bug_name
- old_pkg = pkg_name
- old_dsc = desc
- outrel = []
- outrel.append( release )
- yield old_pkg, self.make_xref(url, old_bug), old_dsc, ', '.join(outrel)
-
- return self.create_page(url, 'Packages that have open unimportant issues',
- [P("""This page lists packages that are affected by issues
- that are considered unimportant from a security perspective.
- These issues are thought to be unexploitable or uneffective
- in most situations (for example, browser denial-of-services)."""),
- make_table(gen(), caption=('Package', 'Bug', 'Description', 'Releases'))])
+ with self.open_db() as db:
+ def gen():
+ outrel = []
+ old_bug = ''
+ old_pkg = ''
+ old_dsc = ''
+ old_name = ''
+ last_displayed = ''
+ releases = config.get_supported_releases()
+ for (pkg_name, bug_name, release, desc) in db.cursor().execute(
+ """SELECT DISTINCT sp.name, st.bug_name, sp.release,
+ bugs.description
+ FROM source_package_status AS st, source_packages AS sp, bugs
+ WHERE st.vulnerable != ? AND sp.rowid = st.package
+ AND sp.release IN (""" + ",".join("?" * len(releases)) + """)
+ AND st.urgency == 'unimportant'
+ AND sp.subrelease = '' AND st.bug_name == bugs.name
+ ORDER BY sp.name, st.bug_name COLLATE version""",
+ (security_db.Vulnerable.FIXED, *releases)):
+
+ if old_bug == '':
+ old_bug = bug_name
+ old_pkg = pkg_name
+ old_dsc = desc
+ elif old_bug != bug_name:
+ if old_pkg == last_displayed:
+ to_display = ''
+ else:
+ to_display = old_pkg
+ yield to_display, self.make_xref(url, old_bug), old_dsc, ', '.join(outrel)
+ last_displayed = old_pkg
+ old_bug = bug_name
+ old_pkg = pkg_name
+ old_dsc = desc
+ outrel = []
+ outrel.append( release )
+ yield old_pkg, self.make_xref(url, old_bug), old_dsc, ', '.join(outrel)
+
+ return self.create_page(url, 'Packages that have open unimportant issues',
+ [P("""This page lists packages that are affected by issues
+ that are considered unimportant from a security perspective.
+ These issues are thought to be unexploitable or uneffective
+ in most situations (for example, browser denial-of-services)."""),
+ make_table(gen(), caption=('Package', 'Bug', 'Description', 'Releases'))])
def page_status_itp(self, path, params, url):
- def gen():
- old_pkg = ''
- for pkg, bugs, debian_bugs in self.db.getITPs(self.db.cursor()):
- if pkg == old_pkg:
- pkg = ''
- else:
- old_pkg = pkg
- yield (pkg, self.make_xref_list(url, bugs),
- self.make_debian_bug_list(url, debian_bugs))
- return self.create_page(
- url, "ITPs with potential security issues",
- [make_table(gen(), caption=("Package", "Issue", "Debian Bugs"),
- replacement="No ITP bugs are currently known.")])
+ with self.open_db() as db:
+ def gen():
+ old_pkg = ''
+ for pkg, bugs, debian_bugs in db.getITPs(db.cursor()):
+ if pkg == old_pkg:
+ pkg = ''
+ else:
+ old_pkg = pkg
+ yield (pkg, self.make_xref_list(url, bugs),
+ self.make_debian_bug_list(url, debian_bugs))
+ return self.create_page(
+ url, "ITPs with potential security issues",
+ [make_table(gen(), caption=("Package", "Issue", "Debian Bugs"),
+ replacement="No ITP bugs are currently known.")])
def page_status_unreported(self, path, params, url):
show_ignored = params.get('show_ignored', False)
@@ -1056,210 +1071,219 @@ checker to find out why they have not entered testing yet."""),
else:
flags = A(url.updateParamsDict({'show_ignored' : '1'}),
'Show ignored issues')
- def gen():
- for (bug, packages) in self.db.getUnreportedVulnerabilities(show_ignored=show_ignored_flag):
- pkgs = make_list([self.make_source_package_ref(url, pkg)
- for pkg in packages], ", ")
- yield self.make_xref(url, bug), pkgs
- return self.create_page(
- url, "Unfixed vulnerabilities in unstable without a filed bug",
- [P(flags), P("""The list below contains vulnerabilities for which no matching
-Debian bug has been filed, and there is still an unfixed package in sid."""),
- make_table(gen(), caption=("Bug", "Packages"))])
+ with self.open_db() as db:
+ def gen():
+ for (bug, packages) in db.getUnreportedVulnerabilities(show_ignored=show_ignored_flag):
+ pkgs = make_list([self.make_source_package_ref(url, pkg)
+ for pkg in packages], ", ")
+ yield self.make_xref(url, bug), pkgs
+ return self.create_page(
+ url, "Unfixed vulnerabilities in unstable without a filed bug",
+ [P(flags), P("""The list below contains vulnerabilities for which no matching
+ Debian bug has been filed, and there is still an unfixed package in sid."""),
+ make_table(gen(), caption=("Bug", "Packages"))])
def page_data_unknown_packages(self, path, params, url):
- def gen():
- for name, bugs in self.db.getUnknownPackages(self.db.cursor()):
- yield name, self.make_xref_list(url, bugs)
- return self.create_page(
- url, "Unknown packages",
- [P("""Sometimes, a package referenced in a bug report
-cannot be found in the database. This can be the result of a spelling
-error, or a historic entry refers to a
-package which is no longer in the archive."""),
- make_table(gen(), caption=("Package", "Bugs"),
- replacement="No unknown packages are referenced in the database.")])
+ with self.open_db() as db:
+ def gen():
+ for name, bugs in db.getUnknownPackages(db.cursor()):
+ yield name, self.make_xref_list(url, bugs)
+ return self.create_page(
+ url, "Unknown packages",
+ [P("""Sometimes, a package referenced in a bug report
+ cannot be found in the database. This can be the result of a spelling
+ error, or a historic entry refers to a
+ package which is no longer in the archive."""),
+ make_table(gen(), caption=("Package", "Bugs"),
+ replacement="No unknown packages are referenced in the database.")])
def page_data_missing_epochs(self, path, params, url):
- def gen():
- old_bug = ''
- old_pkg = ''
- for bug, pkg, ver1, ver2 in self.db.cursor().execute(
- """SELECT DISTINCT bug_name, n.package,
- n.fixed_version, sp.version
- FROM package_notes AS n, source_packages AS sp
- WHERE n.package_kind = 'source'
- AND n.fixed_version NOT LIKE '%:%'
- AND n.fixed_version <> '0'
- AND n.bug_origin = ''
- AND sp.name = n.package
- AND sp.version LIKE '%:%'
- ORDER BY bug_name COLLATE version, package"""):
- if bug == old_bug:
- bug = ''
- else:
- old_bug = bug
- old_pkg = ''
- bug = self.make_xref(url, bug)
- if pkg == old_pkg:
- pkg = ''
- else:
- old_pkg = pkg
- pkg = self.make_source_package_ref(url, pkg)
- yield bug, pkg, ver1, ver2
+ with self.open_db() as db:
+ def gen():
+ old_bug = ''
+ old_pkg = ''
+ for bug, pkg, ver1, ver2 in db.cursor().execute(
+ """SELECT DISTINCT bug_name, n.package,
+ n.fixed_version, sp.version
+ FROM package_notes AS n, source_packages AS sp
+ WHERE n.package_kind = 'source'
+ AND n.fixed_version NOT LIKE '%:%'
+ AND n.fixed_version <> '0'
+ AND n.bug_origin = ''
+ AND sp.name = n.package
+ AND sp.version LIKE '%:%'
+ ORDER BY bug_name COLLATE version, package"""):
+ if bug == old_bug:
+ bug = ''
+ else:
+ old_bug = bug
+ old_pkg = ''
+ bug = self.make_xref(url, bug)
+ if pkg == old_pkg:
+ pkg = ''
+ else:
+ old_pkg = pkg
+ pkg = self.make_source_package_ref(url, pkg)
+ yield bug, pkg, ver1, ver2
- return self.create_page(
- url, "Missing epochs in package versions",
- [make_table(gen(),
- caption=("Bug", "Package", "Version 1", "Version 2"),
- replacement="No source package version with missing epochs.")])
+ return self.create_page(
+ url, "Missing epochs in package versions",
+ [make_table(gen(),
+ caption=("Bug", "Package", "Version 1", "Version 2"),
+ replacement="No source package version with missing epochs.")])
def page_data_latently_vulnerable(self, path, params, url):
- def gen():
- for pkg, bugs in self.db.cursor().execute(
- """SELECT package, string_set(bug_name)
- FROM package_notes AS p1
- WHERE release <> ''
- AND (bug_name LIKE 'CVE-%' OR bug_name LIKE 'TEMP-%')
- AND NOT EXISTS (SELECT 1 FROM package_notes AS p2
- WHERE p2.bug_name = p1.bug_name
- AND p2.package = p1.package
- AND release = '')
- AND EXISTS (SELECT 1 FROM source_packages
- WHERE name = p1.package AND release = 'sid')
- GROUP BY package
- ORDER BY package"""):
- pkg = self.make_source_package_ref(url, pkg)
- bugs = bugs.split(',')
- yield pkg, self.make_xref_list(url, bugs)
-
- def gen_unimportant():
- for pkg, bugs in self.db.cursor().execute(
- """SELECT package, string_set(bug_name)
- FROM package_notes AS p1
- WHERE release <> ''
- AND urgency <> 'unimportant'
- AND (bug_name LIKE 'CVE-%' OR bug_name LIKE 'TEMP-%')
- AND EXISTS (SELECT 1 FROM package_notes AS p2
- WHERE p2.bug_name = p1.bug_name
- AND p2.package = p1.package
- AND release = '')
- AND NOT EXISTS (SELECT 1 FROM package_notes AS p2
- WHERE p2.bug_name = p1.bug_name
- AND p2.package = p1.package
- AND urgency <> 'unimportant'
- AND release = '')
- AND EXISTS (SELECT 1 FROM source_packages
- WHERE name = p1.package AND release = 'sid')
- GROUP BY package
- ORDER BY package"""):
- pkg = self.make_source_package_ref(url, pkg)
- bugs = bugs.split(',')
- yield pkg, self.make_xref_list(url, bugs)
+ with self.open_db() as db:
+ def gen():
+ for pkg, bugs in db.cursor().execute(
+ """SELECT package, string_set(bug_name)
+ FROM package_notes AS p1
+ WHERE release <> ''
+ AND (bug_name LIKE 'CVE-%' OR bug_name LIKE 'TEMP-%')
+ AND NOT EXISTS (SELECT 1 FROM package_notes AS p2
+ WHERE p2.bug_name = p1.bug_name
+ AND p2.package = p1.package
+ AND release = '')
+ AND EXISTS (SELECT 1 FROM source_packages
+ WHERE name = p1.package AND release = 'sid')
+ GROUP BY package
+ ORDER BY package"""):
+ pkg = self.make_source_package_ref(url, pkg)
+ bugs = bugs.split(',')
+ yield pkg, self.make_xref_list(url, bugs)
+
+ def gen_unimportant():
+ for pkg, bugs in db.cursor().execute(
+ """SELECT package, string_set(bug_name)
+ FROM package_notes AS p1
+ WHERE release <> ''
+ AND urgency <> 'unimportant'
+ AND (bug_name LIKE 'CVE-%' OR bug_name LIKE 'TEMP-%')
+ AND EXISTS (SELECT 1 FROM package_notes AS p2
+ WHERE p2.bug_name = p1.bug_name
+ AND p2.package = p1.package
+ AND release = '')
+ AND NOT EXISTS (SELECT 1 FROM package_notes AS p2
+ WHERE p2.bug_name = p1.bug_name
+ AND p2.package = p1.package
+ AND urgency <> 'unimportant'
+ AND release = '')
+ AND EXISTS (SELECT 1 FROM source_packages
+ WHERE name = p1.package AND release = 'sid')
+ GROUP BY package
+ ORDER BY package"""):
+ pkg = self.make_source_package_ref(url, pkg)
+ bugs = bugs.split(',')
+ yield pkg, self.make_xref_list(url, bugs)
- return self.create_page(
- url, "Latently vulnerable packages in unstable",
- [P(
-"""A package is latently vulnerable in unstable if it is vulnerable in
-any release, and there is no package note for the same vulnerability
-and package in unstable (and the package is still available in
-unstable, of course)."""),
- make_table(gen(),
- caption=("Package", "Bugs"),
- replacement="No latently vulnerable packages were found."),
- P(
-"""The next table lists issues which are marked unimportant for
-unstable, but for which release-specific annotations exist which are
-not unimportant."""),
- make_table(gen_unimportant(),
- caption=("Package", "Bugs"),
- replacement=
- "No packages with unimportant latent vulnerabilities were found."),
- ])
+ return self.create_page(
+ url, "Latently vulnerable packages in unstable",
+ [P(
+ """A package is latently vulnerable in unstable if it is vulnerable in
+ any release, and there is no package note for the same vulnerability
+ and package in unstable (and the package is still available in
+ unstable, of course)."""),
+ make_table(gen(),
+ caption=("Package", "Bugs"),
+ replacement="No latently vulnerable packages were found."),
+ P(
+ """The next table lists issues which are marked unimportant for
+ unstable, but for which release-specific annotations exist which are
+ not unimportant."""),
+ make_table(gen_unimportant(),
+ caption=("Package", "Bugs"),
+ replacement=
+ "No packages with unimportant latent vulnerabilities were found."),
+ ])
def page_data_releases(self, path, params, url):
- def gen():
- for (rel, subrel, archive, sources, archs) \
- in self.db.availableReleases():
- if 'source' in archs:
- archs.remove('source')
- yield rel, subrel, archive, "yes" if sources else "no" , make_list(archs)
- return self.create_page(
- url, "Available releases",
- [P("""The security issue database is checked against
-the Debian releases listed in the table below."""),
- make_table(gen(),
- caption=("Release", "Subrelease", "Archive",
- "Sources", "Architectures"))])
+ with self.open_db() as db:
+ def gen():
+ for (rel, subrel, archive, sources, archs) \
+ in db.availableReleases():
+ if 'source' in archs:
+ archs.remove('source')
+ yield rel, subrel, archive, "yes" if sources else "no", make_list(archs)
+ return self.create_page(
+ url, "Available releases",
+ [P("""The security issue database is checked against
+ the Debian releases listed in the table below."""),
+ make_table(gen(),
+ caption=("Release", "Subrelease", "Archive",
+ "Sources", "Architectures"))])
def page_data_funny_versions(self, path, params, url):
- def gen():
- for name, release, archive, version, source_version \
- in self.db.getFunnyPackageVersions():
- yield name, release, archive, source_version, version
+ with self.open_db() as db:
+ def gen():
+ for name, release, archive, version, source_version \
+ in db.getFunnyPackageVersions():
+ yield name, release, archive, source_version, version
- return self.create_page(
- url, "Version conflicts between source/binary packages",
- [P("""The table below lists source packages
- which have a binary package of the same name, but with a different
- version. This means that extra care is necessary to determine
- the version of a package which has been fixed. (Note that
- the bug tracker prefers source versions to binary versions
- in this case.)"""),
- make_table(gen(),
- caption=("Package",
- "Release",
- "Archive",
- "Source Version",
- "Binary Version")),
- P("""Technically speaking, these version numbering is fine,
-but it makes version-based bug tracking quite difficult for these packages."""),
- P("""There are many binary packages which are built from source
- packages with different version numbering schemes. However, as
- long as none of the binary packages carries the same name as the
- source package, most confusion is avoided or can be easily
- explained.""")])
+ return self.create_page(
+ url, "Version conflicts between source/binary packages",
+ [P("""The table below lists source packages
+ which have a binary package of the same name, but with a different
+ version. This means that extra care is necessary to determine
+ the version of a package which has been fixed. (Note that
+ the bug tracker prefers source versions to binary versions
+ in this case.)"""),
+ make_table(gen(),
+ caption=("Package",
+ "Release",
+ "Archive",
+ "Source Version",
+ "Binary Version")),
+ P("""Technically speaking, these version numbering is fine,
+ but it makes version-based bug tracking quite difficult for these packages."""),
+ P("""There are many binary packages which are built from source
+ packages with different version numbering schemes. However, as
+ long as none of the binary packages carries the same name as the
+ source package, most confusion is avoided or can be easily
+ explained.""")])
def page_data_fake_names(self, path, params, url):
- def gen(v):
- for (bug, description) in self.db.getFakeBugs(vulnerability=v):
- yield self.make_xref(url, bug), description
- return self.create_page(
- url, "Automatically generated issue names",
- [P("""Some issues have not been assigned CVE names, but are still
-tracked by this database. In this case, the system automatically assigns
-a unique name. These names are not stable and can change when the database
-is updated, so they should not be used in external references."""),
- P('''The automatically generated names come in two flavors:
-the first kind starts with the string "''', CODE("TEMP-000000-"),
- '''". This means that no Debian bug has been assigned to this
-issue (or a bug has been created and is not recorded in this database).
-In the second kind of names, there is a Debian bug for the issue, and the "''',
- CODE("000000"), '''"part of the name is replaced with the
-Debian bug number.'''),
- make_table(gen(security_db.Vulnerable.AFFECTED),title=H2('With unfixed issues'), caption=("Bug", "Description")),
- make_table(gen(security_db.Vulnerable.FIXED),title=H2('The rest'), caption=("Bug", "Description")),
- ])
+ with self.open_db() as db:
+ def gen(v):
+ for (bug, description) in db.getFakeBugs(vulnerability=v):
+ yield self.make_xref(url, bug), description
+ return self.create_page(
+ url, "Automatically generated issue names",
+ [P("""Some issues have not been assigned CVE names, but are still
+ tracked by this database. In this case, the system automatically assigns
+ a unique name. These names are not stable and can change when the database
+ is updated, so they should not be used in external references."""),
+ P('''The automatically generated names come in two flavors:
+ the first kind starts with the string "''', CODE("TEMP-000000-"),
+ '''". This means that no Debian bug has been assigned to this
+ issue (or a bug has been created and is not recorded in this database).
+ In the second kind of names, there is a Debian bug for the issue, and the "''',
+ CODE("000000"), '''"part of the name is replaced with the
+ Debian bug number.'''),
+ make_table(gen(security_db.Vulnerable.AFFECTED),title=H2('With unfixed issues'), caption=("Bug", "Description")),
+ make_table(gen(security_db.Vulnerable.FIXED),title=H2('The rest'), caption=("Bug", "Description")),
+ ])
def page_data_pts(self, path, params, url):
data = []
- for pkg, bugs in self.db.cursor().execute(
- """SELECT package, COUNT(DISTINCT bug) FROM
- (SELECT package, bug, urgency FROM stable_status
- UNION ALL SELECT DISTINCT sp.name, st.bug_name, st.urgency
- FROM source_package_status AS st, source_packages AS sp
- WHERE st.vulnerable != ? AND st.urgency <> 'unimportant'
- AND sp.rowid = st.package AND sp.release = 'sid'
- AND sp.subrelease = '') x WHERE urgency <> 'unimportant'
- GROUP BY package ORDER BY package""", (security_db.Vulnerable.FIXED,)):
- data.append(pkg)
- data.append(':')
- data.append(str(bugs))
- data.append('\n')
+ with self.open_db() as db:
+ for pkg, bugs in db.cursor().execute(
+ """SELECT package, COUNT(DISTINCT bug) FROM
+ (SELECT package, bug, urgency FROM stable_status
+ UNION ALL SELECT DISTINCT sp.name, st.bug_name, st.urgency
+ FROM source_package_status AS st, source_packages AS sp
+ WHERE st.vulnerable != ? AND st.urgency <> 'unimportant'
+ AND sp.rowid = st.package AND sp.release = 'sid'
+ AND sp.subrelease = '') x WHERE urgency <> 'unimportant'
+ GROUP BY package ORDER BY package""", (security_db.Vulnerable.FIXED,)):
+ data.append(pkg)
+ data.append(':')
+ data.append(str(bugs))
+ data.append('\n')
return BinaryResult(''.join(data).encode("utf-8"), 'application/octet-stream')
def exported_result(self, path, url):
- data = self.db.getExported(path)
+ with self.open_db() as db:
+ data = db.getExported(path)
if data:
result = BinaryResult(data[0], data[1])
if data[2]:
=====================================
lib/python/security_db.py
=====================================
@@ -321,6 +321,12 @@ class DB:
raise SchemaMismatch(repr(user_version))
self._initViews(c)
+ def __enter__(self):
+ return self
+
+ def __exit__(self, _exc_type, _exc_value, _traceback):
+ self.db.close()
+
def __del__(self):
self.db.close()
=====================================
lib/python/web_support.py
=====================================
@@ -16,7 +16,6 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
import re
-import threading
from urllib.parse import quote as urllib_quote
from urllib.parse import parse_qs
from socketserver import ThreadingMixIn
@@ -623,7 +622,6 @@ class WebServiceHTTPAdapter:
def __init__(self, service: WebServiceBase, socket_name):
self.service = service
(base_url, address, port) = socket_name
- self.lock = threading.Lock()
self.__parse_base_url(base_url)
@@ -639,10 +637,9 @@ class WebServiceHTTPAdapter:
path, params,
secure=adapter_self.service.secure)
- with adapter_self.lock:
- r = method(remaining, params, url)
- assert isinstance(r, Result), repr(r)
- result = r.flatten_later()
+ r = method(remaining, params, url)
+ assert isinstance(r, Result), repr(r)
+ result = r.flatten_later()
result(self)
do_HEAD = do_GET
View it on GitLab: https://salsa.debian.org/security-tracker-team/security-tracker/-/compare/51dd23e636e7f1a62b8749510666cbd56ca378b8...5eea0a77db7dc347d4e259aa1cd5c7b9550a8684
--
View it on GitLab: https://salsa.debian.org/security-tracker-team/security-tracker/-/compare/51dd23e636e7f1a62b8749510666cbd56ca378b8...5eea0a77db7dc347d4e259aa1cd5c7b9550a8684
You're receiving this email because of your account on salsa.debian.org. Manage all notifications: https://salsa.debian.org/-/profile/notifications | Help: https://salsa.debian.org/help
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/debian-security-tracker-commits/attachments/20260824/62ccb3b1/attachment-0001.htm>
More information about the debian-security-tracker-commits
mailing list