Skip to content

Commit 0c7dfa3

Browse files
committed
Merged revisions 67528 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk ........ r67528 | fred.drake | 2008-12-04 13:25:17 -0500 (Thu, 04 Dec 2008) | 4 lines Issue #1055234: cgi.parse_header(): Fixed parsing of header parameters to support unusual filenames (such as those containing semi-colons) in Content-Disposition headers. ........
1 parent 8ad4f80 commit 0c7dfa3

File tree

3 files changed

+45
-3
lines changed

3 files changed

+45
-3
lines changed

Lib/cgi.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -289,16 +289,28 @@ def parse_multipart(fp, pdict):
289289
return partdict
290290

291291

292+
def _parseparam(s):
293+
while s[:1] == ';':
294+
s = s[1:]
295+
end = s.find(';')
296+
while end > 0 and s.count('"', 0, end) % 2:
297+
end = s.find(';', end + 1)
298+
if end < 0:
299+
end = len(s)
300+
f = s[:end]
301+
yield f.strip()
302+
s = s[end:]
303+
292304
def parse_header(line):
293305
"""Parse a Content-type like header.
294306
295307
Return the main content-type and a dictionary of options.
296308
297309
"""
298-
plist = [x.strip() for x in line.split(';')]
299-
key = plist.pop(0).lower()
310+
parts = _parseparam(';' + line)
311+
key = parts.next()
300312
pdict = {}
301-
for p in plist:
313+
for p in parts:
302314
i = p.find('=')
303315
if i >= 0:
304316
name = p[:i].strip().lower()

Lib/test/test_cgi.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,32 @@ def test_deprecated_parse_qsl(self):
354354
self.assertEqual([('a', 'A1'), ('b', 'B2'), ('B', 'B3')],
355355
cgi.parse_qsl('a=A1&b=B2&B=B3'))
356356

357+
def test_parse_header(self):
358+
self.assertEqual(
359+
cgi.parse_header("text/plain"),
360+
("text/plain", {}))
361+
self.assertEqual(
362+
cgi.parse_header("text/vnd.just.made.this.up ; "),
363+
("text/vnd.just.made.this.up", {}))
364+
self.assertEqual(
365+
cgi.parse_header("text/plain;charset=us-ascii"),
366+
("text/plain", {"charset": "us-ascii"}))
367+
self.assertEqual(
368+
cgi.parse_header('text/plain ; charset="us-ascii"'),
369+
("text/plain", {"charset": "us-ascii"}))
370+
self.assertEqual(
371+
cgi.parse_header('text/plain ; charset="us-ascii"; another=opt'),
372+
("text/plain", {"charset": "us-ascii", "another": "opt"}))
373+
self.assertEqual(
374+
cgi.parse_header('attachment; filename="silly.txt"'),
375+
("attachment", {"filename": "silly.txt"}))
376+
self.assertEqual(
377+
cgi.parse_header('attachment; filename="strange;name"'),
378+
("attachment", {"filename": "strange;name"}))
379+
self.assertEqual(
380+
cgi.parse_header('attachment; filename="strange;name";size=123;'),
381+
("attachment", {"filename": "strange;name", "size": "123"}))
382+
357383

358384
def test_main():
359385
run_unittest(CgiTests)

Misc/NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ Core and Builtins
5252
Library
5353
-------
5454

55+
- Issue #1055234: cgi.parse_header(): Fixed parsing of header parameters to
56+
support unusual filenames (such as those containing semi-colons) in
57+
Content-Disposition headers.
58+
5559
- Issue #3741: DISTUTILS_USE_SDK set causes msvc9compiler.py to raise an
5660
exception.
5761

0 commit comments

Comments
 (0)