Ticket #732 (defect)
Opened 2 years ago
Last modified 1 year 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.
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.


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.