Edgewall Software

Opened 7 years ago

Closed 7 years ago

#12613 closed defect (fixed)

TracSpamFilter causes exception on /about page

Reported by: Rainer Müller <raimue@…> Owned by: Jun Omae
Priority: normal Milestone: 1.0.14
Component: general Version:
Severity: normal Keywords:
Cc: Branch:
Release Notes:

Fix get_pkginfo() not working with a file metadata.

API Changes:
Internal Changes:


On visiting /about, I encountered the following exception:

2016-10-24 09:59:10,686 Trac[main] ERROR: Internal Server Error: <RequestWithSession "GET '/about'">, referrer None
Traceback (most recent call last):
  File "/var/www/trac/virtualenv/lib/python2.7/site-packages/trac/web/main.py", line 562, in _dispatch_request
  File "/var/www/trac/virtualenv/lib/python2.7/site-packages/trac/web/main.py", line 249, in dispatch
    resp = chosen_handler.process_request(req)
  File "/var/www/trac/virtualenv/lib/python2.7/site-packages/trac/about.py", line 66, in process_request
    data['systeminfo'] = self.env.get_systeminfo()
  File "/var/www/trac/virtualenv/lib/python2.7/site-packages/trac/env.py", line 304, in get_systeminfo
    info.extend(provider.get_system_info() or [])
  File "/var/www/trac/virtualenv/lib/python2.7/site-packages/tracspamfilter/filtersystem.py", line 456, in get_system_info
    yield 'dnspython', get_pkginfo(dns)['version']
KeyError: 'version'

This is on a standard Debian 8 jessie installation, with python-dnspython 1.12.0-1. The trac.util.get_pkginfo function returns an empty dict when asking for the version of the module. This in itself might be another bug in Trac or it needs to be fixed in Debian's packaging.

$ python -c 'import dns; from trac.util import get_pkginfo; print get_pkginfo(dns)'

Attachments (1)

tracspamfilter-get-pkginfo.diff (442 bytes ) - added by Rainer Müller <raimue@…> 7 years ago.

Download all attachments as: .zip

Change History (7)

by Rainer Müller <raimue@…>, 7 years ago


comment:1 by Rainer Müller <raimue@…>, 7 years ago

The attached patch mitigates the problem by using .get('version') to access the value. Instead of throwing an exception, an empty version will be displayed on the /about page if the version cannot be determined.

comment:2 by Jun Omae, 7 years ago

Hmmm, the python-dnspython package has *.egg-info metadata however it is single file rather that a directory which contains *.egg-info/PKG-INFO. The get_pkginfo() utility doesn't work with metadata as a file.

$ dpkg --listfiles python-dnspython | grep info
$ ls -la /usr/lib/python2.7/dist-packages/dnspython-1.12.0.egg-info
-rw-r--r--. 1 root root 1280 Sep 15  2014 /usr/lib/python2.7/dist-packages/dnspython-1.12.0.egg-info
$ cat /usr/lib/python2.7/dist-packages/dnspython-1.12.0.egg-info
Metadata-Version: 1.1
Name: dnspython
Version: 1.12.0
Summary: DNS toolkit
Home-page: http://www.dnspython.org
Version 0, edited 7 years ago by Jun Omae (next)

comment:3 by Jun Omae, 7 years ago

Could you try the following patch?

  • trac/util/__init__.py

    diff --git a/trac/util/__init__.py b/trac/util/__init__.py
    index 2ca6ab62f..605e6bafb 100644
    a b def get_pkginfo(dist):  
    730730    Always returns a dictionary but it will be empty if no Distribution
    731731    instance can be created for the given module.
    732732    """
     733    import email
    733734    import types
    734735    if isinstance(dist, types.ModuleType):
    735         def has_resource(dist, resource_name):
     736        def has_resource(dist, module, resource_name):
    736737            if dist.location.endswith('.egg'):  # installed by easy_install
    737738                return dist.has_resource(resource_name)
    738739            if dist.has_metadata('installed-files.txt'):  # installed by pip
    def get_pkginfo(dist):  
    747748            if dist.has_metadata('RECORD'):  # *.dist-info/RECORD
    748749                reader = csv.reader(StringIO(dist.get_metadata('RECORD')))
    749750                return any(resource_name == row[0] for row in reader)
     751            if dist.has_metadata('PKG-INFO'):
     752                try:
     753                    pkginfo = email.message_from_string(
     754                                                dist.get_metadata('PKG-INFO'))
     755                    if module.__name__ in pkginfo.get_all('Provides', ()):
     756                        return True
     757                except (IOError, email.Errors.MessageError):
     758                    pass
    750759            toplevel = resource_name.split('/')[0]
    751760            if dist.has_metadata('top_level.txt'):
    752761                return toplevel in dist.get_metadata_lines('top_level.txt')
    def get_pkginfo(dist):  
    761770            resource_name += '.py'
    762771        for dist in find_distributions(module_path, only=True):
    763772            if os.path.isfile(module_path) or \
    764                     has_resource(dist, resource_name):
     773                    has_resource(dist, module, resource_name):
    765774                break
    766775        else:
    767776            return {}
    768     import email
    769777    from trac.util.translation import _
    770778    attrs = ('author', 'author-email', 'license', 'home-page', 'summary',
    771779             'description', 'version')

After the patch:

>>> import dns
>>> from trac.util import get_pkginfo
>>> pkginfo = get_pkginfo(dns)
>>> pkginfo['version']
>>> pkginfo['summary']
'DNS toolkit'
Last edited 7 years ago by Jun Omae (previous) (diff)

comment:4 by Rainer Müller <raimue@…>, 7 years ago

Yes, this patch works for me and would resolve the problem.

comment:5 by Jun Omae, 7 years ago

Component: plugin/spamfiltergeneral
Milestone: plugin - spam-filter1.0.14
Owner: changed from Dirk Stöcker to Jun Omae
Status: newassigned

Thanks for the feedback. I'll apply the patch to 1.0-stable branch (with unit tests if possible).

comment:6 by Jun Omae, 7 years ago

Release Notes: modified (diff)
Resolution: fixed
Status: assignedclosed

Fixed in [15189] and merged in [15190-15191].

Modify Ticket

Change Properties
Set your email in Preferences
as closed The owner will remain Jun Omae.
The resolution will be deleted. Next status will be 'reopened'.
to The owner will be changed from Jun Omae to the specified user.

Add Comment

E-mail address and name can be saved in the Preferences .
Note: See TracTickets for help on using tickets.