Description
With Python 2.7.5 (and probably 2.7.4) /action/rss_rc.py causes a traceback:
mod_wsgi (pid=26537): Exception occurred processing WSGI script '/home/rockart/webapps/web/drawiki/moin.wsgi'. Traceback (most recent call last): File "/home/rockart/webapps/web/drawiki/MoinMoin/support/werkzeug/wsgi.py", line 411, in __call__ return self.app(environ, start_response) File "/home/rockart/webapps/web/drawiki/MoinMoin/wsgiapp.py", line 282, in __call__ response = run(context) File "/home/rockart/webapps/web/drawiki/MoinMoin/wsgiapp.py", line 88, in run response = dispatch(request, context, action_name) File "/home/rockart/webapps/web/drawiki/MoinMoin/wsgiapp.py", line 136, in dispatch response = handle_action(context, pagename, action_name) File "/home/rockart/webapps/web/drawiki/MoinMoin/wsgiapp.py", line 195, in handle_action handler(context.page.page_name, context) File "/home/rockart/webapps/web/drawiki/MoinMoin/action/rss_rc.py", line 162, in execute handler._out.write(unicode( AttributeError: RssGenerator instance has no attribute '_out'
The problem may be that _out was removed from xml.sax.saxutils.XMLGenerator in Python 2.7.4. Line 162 of /action/rss_rc.py is:
handler._out.write(unicode( '<!--\n' ' Add an "items=nnn" URL parameter to get more than the \n' ' default %(def_max_items)d items. You cannot get more than \n' ' %(items_limit)d items though.\n' ' \n' ' Add "unique=1" to get a list of changes where page names are unique,\n' ' i.e. where only the latest change of each page is reflected.\n' ' \n' ' Add "diffs=1" to add change diffs to the description of each items.\n' ' \n' ' Add "ddiffs=1" to link directly to the diff (good for FeedReader).\n' ' \n' ' Add "lines=nnn" to change maximum number of diff/body lines \n' ' to show. Cannot be more than %(lines_limit)d.\n' ' \n' ' Add "show_att=1" to show items related to attachments.\n' ' \n' ' Add "page=pattern" to show feed only for specific pages.\n' ' Pattern can be empty (it would match to all pages), \n' ' can start with circumflex (it would be interpreted as \n' ' regular expression in this case), end with slash (for \n' ' getting feed for page tree) or point to specific page (if \n' ' none of the above can be applied).\n' ' \n' ' Current settings: items=%(max_items)i, unique=%(unique)i, \n' ' diffs=%(diffs)i, ddiffs=%(ddiffs)i, lines=%(max_lines)i, \n' ' show_att=%(show_att)i\n' '-->\n' % locals() ).encode(config.charset))
Steps to reproduce
Using Python 2.7.4+ attempt to access something like:
Note: The only known use of the above link are 3+ bots that are attempting to follow the link below from the html header (started 2 days ago with repeated attempts every 5 minutes):
<link rel="alternate" title="DigitalRockArt Wiki: IntroductionToDigitalRockArt" href="/drawiki/IntroductionToDigitalRockArt?diffs=1&show_att=1&action=rss_rc&unique=0&page=IntroductionToDigitalRockArt&ddiffs=1" type="application/rss+xml">
Example
Component selection
- actions
Details
MoinMoin Version |
1.9.6 |
OS and Version |
Centos 5 |
Python Version |
2.7.5 |
Server Setup |
apache |
Server Details |
wsgi |
Language you are using the wiki in (set in the browser/UserPreferences) |
en |
Workaround
Replace handler._out.write(unicode( with handler._write(unicode( and delete .encode(config.charset) -- creates ugly output but eliminates the 500 server errors.
Discussion
Plan
- Priority:
- Assigned to:
Status: fixed by http://hg.moinmo.in/moin/1.9/rev/aee4ff651134 and http://hg.moinmo.in/moin/1.9/rev/6de72050e1b9
Note: The above fix is not correct. Instead of replacing handler._out.write(unicode( with handler._write(unicode( and deleting .encode(config.charset) as suggested in the workaround, it replaces handler._out.write(unicode( with handler._write( and deletes .encode(config.charset)). The unicode( and the final ) should remain. Without that, the _write() method is given a string rather than a unicode and throws a TypeError. -- MarkSapiro 2014-10-12 01:08:44
Well, I guess I tested the fix back then when I made it and it worked for me. But maybe instead of verbally describing changes you think are better, can you please just give a diff of what you propose? And also, if you get an exception with the current code, I'ld also like to see the full traceback. -- ThomasWaldmann 2014-10-13 16:24:38
To clarify about removal of unicode(x): such an operation is pointless except when x is str and pure ascii. If x is str and not pure ascii, all unicode(x) will give you is an UnicodeDecodeError as it'll try to decode the str using the default ascii decoder and that will crash for everything non-ascii. That's why after changeset 6de72050e1b9 (which you maybe have not seen as it was not linked to at first) it just uses a unicode literal format string. Arguments that replace placeholders in it are expected to be either str-pure-ascii or unicode. -- ThomasWaldmann 2014-10-13 16:47:57
What I proposed was instead of http://hg.moinmo.in/moin/1.9/rev/aee4ff651134, the following:
diff -r 4790615ddfb6 -r aee4ff651134 MoinMoin/action/rss_rc.py --- a/MoinMoin/action/rss_rc.py Wed Jun 05 00:37:14 2013 +0200 +++ b/MoinMoin/action/rss_rc.py Sat Jun 08 02:25:24 2013 +0200 @@ -159,7 +159,7 @@ # start SAX stream handler.startDocument() - handler._out.write(unicode( + handler._write(unicode( '<!--\n' ' Add an "items=nnn" URL parameter to get more than the \n' ' default %(def_max_items)d items. You cannot get more than \n' @@ -188,7 +188,7 @@ ' diffs=%(diffs)i, ddiffs=%(ddiffs)i, lines=%(max_lines)i, \n' ' show_att=%(show_att)i\n' '-->\n' % locals() - ).encode(config.charset)) + )) # emit channel description handler.startNode('channel', {
With just http://hg.moinmo.in/moin/1.9/rev/aee4ff651134 installed, I got
2014-10-11 17:13:35,330 MoinMoin.wsgiapp ERROR An exception has occurred [http://munged.invalid/wiki/RecentChanges?action=rss_rc&unique=1&ddiffs=1]. Traceback (most recent call last): File "/usr/lib/python2.7/site-packages/MoinMoin/wsgiapp.py", line 282, in __call__ response = run(context) File "/usr/lib/python2.7/site-packages/MoinMoin/wsgiapp.py", line 88, in run response = dispatch(request, context, action_name) File "/usr/lib/python2.7/site-packages/MoinMoin/wsgiapp.py", line 136, in dispatch response = handle_action(context, pagename, action_name) File "/usr/lib/python2.7/site-packages/MoinMoin/wsgiapp.py", line 195, in handle_action handler(context.page.page_name, context) File "/usr/lib/python2.7/site-packages/MoinMoin/action/rss_rc.py", line 190, in execute '-->\n' % locals() File "/usr/lib/python2.7/xml/sax/saxutils.py", line 103, in write super(UnbufferedTextIOWrapper, self).write(s) TypeError: must be unicode, not str
I agree that changing the argument text to unicode rather than string as was done with http://hg.moinmo.in/moin/1.9/rev/6de72050e1b9 fixes the problem with http://hg.moinmo.in/moin/1.9/rev/6de72050e1b9 alone, but since the later patch wasn't referenced here before now, and I'm not that familiar with Mercurial, I wasn't aware of it. -- MarkSapiro 2014-10-13 19:02:09