Download Install Tutorial Docs FAQ Tools WikiLicense Team IRC Planet Involvement Shop Book

Ticket #732 (defect)

Opened 2 years ago

Last modified 3 months ago

tools.decode and non str params

Status: closed (fixed)

Reported by: d.rothe@semantics.de Assigned to: fumanchu
Priority: normal Milestone: 3.1.2
Component: CherryPy code Keywords:
Cc:

tools.decode does not handle non str params well.

using cp.3.0.2

After handling all the request-parameter decoding by myself (never sure I got it right), I checked out tools.decode.

It seems like this tool expects as parameters only strings and lists of strings. But I'm using the routes-dispatcher wich defaults some parameters to "None" for example. The tool tries to decode that "None" - bang.

I have modified the subroutine decode_params of the decode tool which reflects this.

def decode_params(encoding):
    decoded_params = {}
    for key, value in cherrypy.request.params.items():
        if hasattr(value, 'file'):
            # This is a file being uploaded: skip it
            decoded_params[key] = value
        elif isinstance(value, list):
            # value is a list: decode each element
            decoded_params[key] = [v.decode(encoding) for v in value]
        elif isinstance(value, unicode):
            #dirk: keep unicode param (move this to else:)
            decoded_params[key] = value
        elif isinstance(value, str):
            # value is a regular string: decode it
            decoded_params[key] = value.decode(encoding)
        else:
            # dirk: value is something else (maybe modified by a custom dispatcher)
            # keep it
            decoded_params[key] = value

    # Decode all or nothing, so we can try again on error.
    cherrypy.request.params = decoded_params

Change History

09/20/07 17:26:06: Modified by fumanchu

  • owner changed from rdelon to fumanchu.
  • status changed from new to assigned.
  • description changed.

09/20/07 17:31:13: Modified by fumanchu

  • status changed from assigned to closed.
  • resolution set to fixed.

Fixed in [1722]. I'm not 100% sure I like having non-string params in the first place, but allowing them might make the exposed function more readable, especially if someone is doing some form validation and type coercion before the handler is called. Yet Another Example of the fine line between HTTP-ness and Object-ness.

03/24/09 07:43:51: Modified by d.rothe@semantics.de

  • status changed from closed to reopened.
  • resolution deleted.

I've got this one another time. This time two uploaded files with the same FormField-Name. Since uploaded files are of the type cgi.FieldStorage? and the two similarly named files are collaped into a list structure, the decoding failes (with an AttributeError?).

Here is the patch to skip encoding for non-str Values in lists.

Index: lib/encoding.py
===================================================================
--- lib/encoding.py	(revision 13604)
+++ lib/encoding.py	(working copy)
@@ -38,7 +38,7 @@
             # Skip the value if it is an uploaded file
             if isinstance(value, list):
                 # value is a list: decode each element
-                value = [v.decode(encoding) for v in value]
+                value = [v.decode(encoding) if isinstance(v, str) else v for v in value]
             elif isinstance(value, str):
                 # value is a regular string: decode it
                 value = value.decode(encoding)

03/24/09 07:44:21: Modified by d.rothe@semantics.de

  • milestone changed from 3.1 to 3.1.2.

04/01/09 14:55:54: Modified by lawouach

  • status changed from reopened to closed.
  • resolution set to fixed.

Good catch. I've reproduced the problem on my machine with the following code snippet:

import cherrypy

class Root:
    @cherrypy.expose
    def index(self):
        return """<html><head /><body>
<form action="/upload" method="post" enctype="multipart/form-data">
<input type="file" name="f0" />
<input type="file" name="f0" />
<input type="submit" />
</form>
</body>
</html>"""

    @cherrypy.expose
    def upload(self, **kwargs):
        return "blah"

if __name__ == "__main__":
    cherrypy.quickstart(Root(), '/', {'/': {'tools.decode.on': True,
                                            'tools.decode.encoding': 'utf-8'}})

The proposed patch fixes the issue in [2235]. I couldn't add a specific unit tests due to the nature of the form enctype but the test suite didn't seem to have problem based on this patch.

Hosted by WebFaction

Log in as guest/cpguest to create tickets