You are viewing a plain text version of this content. The canonical link for it is here.
Posted to mod_python-dev@quetz.apache.org by rm...@pobox.com on 2002/10/03 19:04:42 UTC
Bug in util.py's handling of Content-Type: multipart/*
I've found a bug in mod_python 3.0.0 beta 2. When a form is submitted
with ENCTYPE="multipart/form-data", util.py will create a Field object
for each named form element, but will also create a Field object with
name = None and value = ''. Then when publisher.py would pass the
keyword arguments to the callable object (see my previous patch that
allows for keyword arguments), that Field object would get translated to
a {None: ''} entry in the dictionary, and Python would raise a TypeError
exception: "Keywords must be strings".
I traced the bug back to util.py's FieldStorage.__init__() method. When
it parses POST requests with content type "multipart/*", each line is
read in with:
line = req.readline()
and then the lines are stripped:
sline = line.strip()
But the "sline = line.strip()" code was not duplicated everywhere that
"line = req.readline()" appeared. Thus, the end-of-while-loop condition
of "sline == (boundary + '--')" was never fulfilled.
Besides this, the end-of-while-loop check was in the wrong place. Having
it after the code to create a Field object was causing a last Field
object to be created based on an empty string; this meant that the "if
disp_options.has_key('name')" test was (naturally) failing, so the name
local variable would be set to None, and then a Field object would be
created with name=None. This was what was causing my keyword argument
passing to break in publisher.py.
Finally, I found one other bug in util.py: string objects don't have a
method splitfields() -- the method name is split(). So the following
line was failing:
plist = map(lambda a: a.strip(), line.splitfields(';'))
Instead, it should be:
plist = map(lambda a: a.strip(), line.split(';'))
I created a patch to fix all three of these errors; you'll find it at
the end of this message, after my signature.
--
Robin Munn
rmunn@pobox.com
--- lib/python/mod_python/orig.util.py 2002-10-03 11:24:17.000000000 -0500
+++ lib/python/mod_python/util.py 2002-10-03 11:26:00.000000000 -0500
@@ -168,6 +168,7 @@
sline = line.strip()
while line and sline != boundary:
line = req.readline()
+ sline = line.strip()
while 1:
@@ -177,6 +178,10 @@
disp, disp_options = None, {}
headers = apache.make_table()
line = req.readline()
+ sline = line.strip()
+ if not line or sline == (boundary + "--"):
+ break
+
while line and line not in ["\n", "\r\n"]:
h, v = line.split(":", 1)
headers.add(h, v)
@@ -186,6 +191,7 @@
elif h == "content-type":
ctype, type_options = parse_header(v)
line = req.readline()
+ sline = line.strip()
if disp_options.has_key("name"):
name = disp_options["name"]
@@ -211,9 +217,6 @@
self.list.append(field)
- if not line or sline == (boundary + "--"):
- break
-
else:
# we don't understand this content-type
raise apache.SERVER_RETURN, apache.HTTP_NOT_IMPLEMENTED
@@ -294,7 +297,7 @@
"""
- plist = map(lambda a: a.strip(), line.splitfields(';'))
+ plist = map(lambda a: a.strip(), line.split(';'))
key = plist[0].lower()
del plist[0]
pdict = {}