diff options
Diffstat (limited to 'Lib/cgi.py')
-rwxr-xr-x | Lib/cgi.py | 38 |
1 files changed, 33 insertions, 5 deletions
diff --git a/Lib/cgi.py b/Lib/cgi.py index ad6b1f88a9..0f50d0e705 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 @@ -76,7 +78,7 @@ def initlog(*allargs): send an error message). """ - global logfp, log + global log, logfile, logfp if logfile and not logfp: try: logfp = open(logfile, "a") @@ -96,6 +98,15 @@ def nolog(*allargs): """Dummy function, assigned to log when logging is disabled.""" pass +def closelog(): + """Close the log file.""" + global log, logfile, logfp + logfile = '' + if logfp: + logfp.close() + logfp = None + log = initlog + log = initlog # The current logging function @@ -463,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__) @@ -627,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): @@ -690,7 +709,7 @@ class FieldStorage: self.encoding, self.errors) self.bytes_read += part.bytes_read self.list.append(part) - if self.bytes_read >= self.length: + if part.done or self.bytes_read >= self.length > 0: break self.skip_lines() @@ -777,6 +796,9 @@ class FieldStorage: if not line: self.done = -1 break + if delim == b"\r": + line = delim + line + delim = b"" if line.startswith(b"--") and last_line_lfend: strippedline = line.rstrip() if strippedline == next_boundary: @@ -793,6 +815,12 @@ class FieldStorage: delim = b"\n" line = line[:-1] last_line_lfend = True + elif line.endswith(b"\r"): + # We may interrupt \r\n sequences if they span the 2**16 + # byte boundary + delim = b"\r" + line = line[:-1] + last_line_lfend = False else: delim = b"" last_line_lfend = False @@ -1003,7 +1031,7 @@ environment as well. Here are some common variable names: def escape(s, quote=None): """Deprecated API.""" warn("cgi.escape is deprecated, use html.escape instead", - PendingDeprecationWarning, stacklevel=2) + DeprecationWarning, stacklevel=2) s = s.replace("&", "&") # Must be done first! s = s.replace("<", "<") s = s.replace(">", ">") |