Merge lp:~thumper/launchpad/fix-dud-referer into lp:launchpad

Proposed by Tim Penhey
Status: Merged
Approved by: Tim Penhey
Approved revision: no longer in the source branch.
Merged at revision: 12775
Proposed branch: lp:~thumper/launchpad/fix-dud-referer
Merge into: lp:launchpad
Diff against target: 64 lines (+29/-6)
2 files modified
lib/canonical/launchpad/webapp/error.py (+9/-1)
lib/canonical/launchpad/webapp/tests/test_publication.py (+20/-5)
To merge this branch: bzr merge lp:~thumper/launchpad/fix-dud-referer
Reviewer Review Type Date Requested Status
Steve Kowalik (community) code Approve
Review via email: mp+56508@code.launchpad.net

Commit message

[r=stevenk][bug=752218] Fix the UnicodeDecodeError when the referer is encoded and the resource is not found.

Description of the change

I was investigating bug 44919, and looking at OOPS-979B2903, OOPS-1921EC1104 and OOPS-979C3111.

The not found page was failing to render due to a unicode decode error on the referer. This is different to the unicode decode error on bug 44919 which as to do with form data.

I managed to replicate the error first. It would oops twice, once for the not found, and a second time when trying to render the page with the bad referer.

The simplest fix was to ignore the referer if it doesn't convert nicely to unicode.

To post a comment you must log in.
Revision history for this message
Steve Kowalik (stevenk) :
review: Approve (code)
Revision history for this message
Robert Collins (lifeless) wrote :

perhaps

if type(referer) != unicode:
    referer = referer.decode('utf8', errors='replace')

instead, which will replace the bad data but leave the rest intact.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/canonical/launchpad/webapp/error.py'
2--- lib/canonical/launchpad/webapp/error.py 2010-12-17 19:16:54 +0000
3+++ lib/canonical/launchpad/webapp/error.py 2011-04-06 05:41:54 +0000
4@@ -209,7 +209,15 @@
5 """
6 referrer = self.request.get('HTTP_REFERER')
7 if referrer:
8- return referrer
9+ # Since this is going to be included in the page template it will
10+ # be coerced into unicode. The byte string representation
11+ # 'should' be ascii, but often it isn't. The only use for this is
12+ # to show a link back to the referring site, so we can't use
13+ # replace or ignore. Best to just pretent it doesn't exist.
14+ try:
15+ return unicode(referrer)
16+ except UnicodeDecodeError:
17+ return None
18 else:
19 return None
20
21
22=== modified file 'lib/canonical/launchpad/webapp/tests/test_publication.py'
23--- lib/canonical/launchpad/webapp/tests/test_publication.py 2011-02-04 14:41:18 +0000
24+++ lib/canonical/launchpad/webapp/tests/test_publication.py 2011-04-06 05:41:54 +0000
25@@ -21,12 +21,11 @@
26 from storm.zope.interfaces import IZStorm
27 from zope.component import getUtility
28 from zope.error.interfaces import IErrorReportingUtility
29-from zope.interface import (
30- directlyProvides,
31- noLongerProvides,
32+from zope.interface import directlyProvides
33+from zope.publisher.interfaces import (
34+ NotFound,
35+ Retry,
36 )
37-from zope.publisher.interfaces import Retry
38-from zope.publisher.interfaces.browser import IBrowserRequest
39
40 from canonical.config import dbconfig
41 from canonical.launchpad.database.emailaddress import EmailAddress
42@@ -440,6 +439,22 @@
43 maybe_block_offsite_form_post(request)
44
45
46+class TestEncodedReferer(TestCaseWithFactory):
47+
48+ layer = DatabaseFunctionalLayer
49+
50+ def test_not_found(self):
51+ # The only oops should be a NotFound.
52+ browser = self.getUserBrowser()
53+ browser.addHeader('Referer', '/whut\xe7foo')
54+ self.assertRaises(
55+ NotFound,
56+ browser.open,
57+ 'http://launchpad.dev/missing')
58+ self.assertEqual(1, len(self.oopses))
59+ self.assertEqual('NotFound', self.oopses[0].type)
60+
61+
62 def test_suite():
63 suite = unittest.TestLoader().loadTestsFromName(__name__)
64 return suite