diff --git a/Lib/httplib.py b/Lib/httplib.py index a63677477d59bb..f9a27619e62685 100644 --- a/Lib/httplib.py +++ b/Lib/httplib.py @@ -365,6 +365,25 @@ def readheaders(self): # It's not a header line; skip it and try the next line. self.status = 'Non-header line where header expected' + +def _read_headers(fp): + """Reads potential header lines into a list from a file pointer. + Length of line is limited by _MAXLINE, and number of + headers is limited by _MAXHEADERS. + """ + headers = [] + while True: + line = fp.readline(_MAXLINE + 1) + if len(line) > _MAXLINE: + raise LineTooLong("header line") + headers.append(line) + if len(headers) > _MAXHEADERS: + raise HTTPException("got more than %d headers" % _MAXHEADERS) + if line in (b'\r\n', b'\n', b''): + break + return headers + + class HTTPResponse: # strict: If true, raise BadStatusLine if the status line can't be @@ -453,15 +472,10 @@ def begin(self): if status != CONTINUE: break # skip the header from the 100 response - while True: - skip = self.fp.readline(_MAXLINE + 1) - if len(skip) > _MAXLINE: - raise LineTooLong("header line") - skip = skip.strip() - if not skip: - break - if self.debuglevel > 0: - print "header:", skip + skipped_headers = _read_headers(self.fp) + if self.debuglevel > 0: + print("headers:", skipped_headers) + del skipped_headers self.status = status self.reason = reason.strip() diff --git a/Lib/test/test_httplib.py b/Lib/test/test_httplib.py index b5fec9aa1ecb9d..d05c0fc28d27ef 100644 --- a/Lib/test/test_httplib.py +++ b/Lib/test/test_httplib.py @@ -700,6 +700,14 @@ def test_overflowing_header_line(self): resp = httplib.HTTPResponse(FakeSocket(body)) self.assertRaises(httplib.LineTooLong, resp.begin) + def test_overflowing_header_limit_after_100(self): + body = ( + 'HTTP/1.1 100 OK\r\n' + 'r\n' * 32768 + ) + resp = httplib.HTTPResponse(FakeSocket(body)) + self.assertRaises(httplib.HTTPException, resp.begin) + def test_overflowing_chunked_line(self): body = ( 'HTTP/1.1 200 OK\r\n' diff --git a/Lib/urllib2.py b/Lib/urllib2.py index fd19e1ae943d1e..e286583ecbac34 100644 --- a/Lib/urllib2.py +++ b/Lib/urllib2.py @@ -858,7 +858,7 @@ class AbstractBasicAuthHandler: # allow for double- and single-quoted realm values # (single quotes are a violation of the RFC, but appear in the wild) - rx = re.compile('(?:.*,)*[ \t]*([^ \t]+)[ \t]+' + rx = re.compile('(?:[^,]*,)*[ \t]*([^ \t,]+)[ \t]+' 'realm=(["\']?)([^"\']*)\\2', re.I) # XXX could pre-emptively send auth info already accepted (RFC 2617,