Warning: Can't synchronize with repository "(default)" (Unsupported version control system "svn": No module named svn). Look in the Trac log for more information.

Ticket #1022 (closed defect: fixed)

Opened 11 years ago

Last modified 10 years ago

IdentityFailure Redirect - Cherrypy causes 500 error if passing compound form values

Reported by: Naomi Owned by: anonymous
Priority: normal Milestone: 1.5
Component: TurboGears Version: 0.9a6
Severity: major Keywords:
Cc:

Description

If a form is submitted after an identity has timed out, IdentityFailure uses cherrypy.InternalRedirect to redirect to identity.failure_url. If the submitted form had compound form values (such as person.firstname and person.lastname), Cherrypy throws the following internal error:

Traceback (most recent call last):
  File "/turbogears/thirdparty/cherrypy/cherrypy/_cphttptools.py", line 104, in _run
    applyFilters('before_main')
  File "/turbogears/thirdparty/cherrypy/cherrypy/filters/__init__.py", line 151, in applyFilters
    method()
  File "/turbogears/thirdparty/cherrypy/cherrypy/filters/decodingfilter.py", line 31, in before_main
    self.decode(enc)
  File "/turbogears/thirdparty/cherrypy/cherrypy/filters/decodingfilter.py", line 50, in decode
    decodedParams[key] = value.decode(enc)
AttributeError: 'dict' object has no attribute 'decode'

The problem occurs in the following chunk of code from cherrypy/_cphttptools.py:

# Loop to allow for InternalRedirect.
while True:
    try:
        applyFilters('before_main')
        if self.execute_main:
            self.main()
            break
        except cherrypy.InternalRedirect, ir:
            self.object_path = ir.path

_cphttptools.py calls applyFilters('before_main') twice: once before the redirect, and once after. The first time through, applyFilters converts the compound form values to dictionaries. The second time through, cherrypy/filters/decodingfilter.py dies because it tries to decode a dictionary.

This should be an easy fix: either only call applyFilters('before_main') the first time, or put a check into decodingfilter.py to make sure you're not trying to decode a dictionary.

Attachments

redirectbug.tgz Download (5.9 KB) - added by Naomi 11 years ago.
Simple project to demonstrate the problem

Change History

Changed 11 years ago by Naomi

Simple project to demonstrate the problem

comment:1 Changed 11 years ago by jorge.vargas

  • Component changed from CherryPy to Identity
  • Milestone set to 1.0

comment:2 Changed 11 years ago by jorge.vargas

  • Milestone changed from 1.0 to 1.0b3

comment:3 Changed 11 years ago by jhb

I filed a bug to cherrypy, along with our solution to the problem:

 http://www.cherrypy.org/ticket/590

Cheers,

jhb

comment:4 Changed 11 years ago by fumanchu

This should be an easy fix: either only call
applyFilters('before_main') the first time,
or put a check into decodingfilter.py to make
sure you're not trying to decode a dictionary.

Well, you don't want all before_main filters to be affected. The proper fix is actually in-between: rewrite just DecodingFilter?.before_main to return if it's run more than once:

class DecodingFilter(BaseFilter):
    """Automatically decodes request parameters (except uploads)."""
    
    def before_main(self):
        conf = cherrypy.config.get
        
        if not conf('decoding_filter.on', False):
            return
        
        if getattr(cherrypy.request, "_decoding_attempted", False):
            return
        cherrypy.request._decoding_attempted = True

This is even more of a problem in CP 3 (since InternalRedirect? may re-execute more filter hook points than just 'before_main'), and CP 3 should gain some facility for managing it better. Would it be worth it for the CP team to patch just this one filter for CP 2.2.2?

comment:5 Changed 10 years ago by alberto

  • Milestone changed from 1.0b3 to 1.1

comment:6 Changed 10 years ago by jorge.vargas

  • Status changed from new to closed
  • Resolution set to invalid

giving this the same as the CP ticket

comment:7 Changed 10 years ago by thesamet

  • Status changed from closed to reopened
  • Resolution invalid deleted
  • Component changed from Identity to TurboGears

The is not a CherryPy? bug because CherryPy? does not expect the params to contain dicts. This issue does not belong to identity, it is coincidental that it pops there.

So to create this problem, it is sufficient to define the following controller method:

def test(self, d):

raise cherrypy.InternalRedirect?('/')

and navigate to /test?d.x=1

It is that after TurboGears' NestedVariablesFilter? does its magic, and the control returns to CherryPy?'s DecodingFilter? things blow out.

comment:8 Changed 10 years ago by faide

  • Status changed from reopened to closed
  • Resolution set to fixed

Fixed in #3771. Thanks Robert for your insights.

comment:9 Changed 10 years ago by roger.demetrescu

Correction: it is fixed in [3771]

Note: See TracTickets for help on using tickets.