From b4cbb92fbe6290c3574e73288de9e9cbb60b7688 Mon Sep 17 00:00:00 2001 From: Senthil Kumaran Date: Sat, 11 Jan 2014 22:20:16 -0800 Subject: [PATCH] Issue #19092 - Raise a correct exception when cgi.FieldStorage is given an invalid file-obj. Also use __bool__ to determine the bool of the FieldStorage object. --- Lib/cgi.py | 14 ++++++++++++-- Lib/test/test_cgi.py | 7 +++++++ Misc/NEWS | 3 +++ 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/Lib/cgi.py b/Lib/cgi.py index 06e03b58588..0f50d0e7059 100755 --- a/Lib/cgi.py +++ b/Lib/cgi.py @@ -32,10 +32,12 @@ __version__ = "2.6" # ======= from io import StringIO, BytesIO, TextIOWrapper +from collections import Mapping import sys import os import urllib.parse from email.parser import FeedParser +from email.message import Message from warnings import warn import html import locale @@ -472,18 +474,24 @@ class FieldStorage: self.qs_on_post = environ['QUERY_STRING'] if 'CONTENT_LENGTH' in environ: headers['content-length'] = environ['CONTENT_LENGTH'] + else: + if not (isinstance(headers, (Mapping, Message))): + raise TypeError("headers must be mapping or an instance of " + "email.message.Message") + self.headers = headers if fp is None: self.fp = sys.stdin.buffer # self.fp.read() must return bytes elif isinstance(fp, TextIOWrapper): self.fp = fp.buffer else: + if not (hasattr(fp, 'read') and hasattr(fp, 'readline')): + raise TypeError("fp must be file pointer") self.fp = fp self.encoding = encoding self.errors = errors - self.headers = headers if not isinstance(outerboundary, bytes): raise TypeError('outerboundary must be bytes, not %s' % type(outerboundary).__name__) @@ -636,7 +644,9 @@ class FieldStorage: """Dictionary style len(x) support.""" return len(self.keys()) - def __nonzero__(self): + def __bool__(self): + if self.list is None: + raise TypeError("Cannot be converted to bool.") return bool(self.list) def read_urlencoded(self): diff --git a/Lib/test/test_cgi.py b/Lib/test/test_cgi.py index d80ec077678..e604c926b9b 100644 --- a/Lib/test/test_cgi.py +++ b/Lib/test/test_cgi.py @@ -137,6 +137,13 @@ class CgiTests(unittest.TestCase): fs.list.append(namedtuple('MockFieldStorage', 'name')('fieldvalue')) self.assertTrue(fs) + def test_fieldstorage_invalid(self): + self.assertRaises(TypeError, cgi.FieldStorage, "not-a-file-obj", + environ={"REQUEST_METHOD":"PUT"}) + self.assertRaises(TypeError, cgi.FieldStorage, "foo", "bar") + fs = cgi.FieldStorage(headers={'content-type':'text/plain'}) + self.assertRaises(TypeError, bool, fs) + def test_escape(self): # cgi.escape() is deprecated. with warnings.catch_warnings(): diff --git a/Misc/NEWS b/Misc/NEWS index f7039919998..552e949cdb5 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -43,6 +43,9 @@ Core and Builtins Library ------- +- Issue #19097: Raise the correct Exception when cgi.FieldStorage is given an + Invalid fileobj. + - Issue #20217: Fix build in SCHED_SPORADIC is defined. - Issue #13107: argparse and optparse no longer raises an exception when output