+56
-5
lines changedFilter options
+56
-5
lines changed Original file line number Diff line number Diff line change
@@ -212,6 +212,9 @@
212
212
# maximal amount of data to read at one time in _safe_read
213
213
MAXAMOUNT = 1048576
214
214
215
+
# maximal line length when calling readline().
216
+
_MAXLINE = 65536
217
+
215
218
class HTTPMessage(mimetools.Message):
216
219
217
220
def addheader(self, key, value):
@@ -274,7 +277,9 @@ def readheaders(self):
274
277
except IOError:
275
278
startofline = tell = None
276
279
self.seekable = 0
277
-
line = self.fp.readline()
280
+
line = self.fp.readline(_MAXLINE + 1)
281
+
if len(line) > _MAXLINE:
282
+
raise LineTooLong("header line")
278
283
if not line:
279
284
self.status = 'EOF in headers'
280
285
break
@@ -404,7 +409,10 @@ def begin(self):
404
409
break
405
410
# skip the header from the 100 response
406
411
while True:
407
-
skip = self.fp.readline().strip()
412
+
skip = self.fp.readline(_MAXLINE + 1)
413
+
if len(skip) > _MAXLINE:
414
+
raise LineTooLong("header line")
415
+
skip = skip.strip()
408
416
if not skip:
409
417
break
410
418
if self.debuglevel > 0:
@@ -563,7 +571,9 @@ def _read_chunked(self, amt):
563
571
value = []
564
572
while True:
565
573
if chunk_left is None:
566
-
line = self.fp.readline()
574
+
line = self.fp.readline(_MAXLINE + 1)
575
+
if len(line) > _MAXLINE:
576
+
raise LineTooLong("chunk size")
567
577
i = line.find(';')
568
578
if i >= 0:
569
579
line = line[:i] # strip chunk-extensions
@@ -598,7 +608,9 @@ def _read_chunked(self, amt):
598
608
# read and discard trailer up to the CRLF terminator
599
609
### note: we shouldn't have any trailers!
600
610
while True:
601
-
line = self.fp.readline()
611
+
line = self.fp.readline(_MAXLINE + 1)
612
+
if len(line) > _MAXLINE:
613
+
raise LineTooLong("trailer line")
602
614
if not line:
603
615
# a vanishingly small number of sites EOF without
604
616
# sending the trailer
@@ -730,7 +742,9 @@ def _tunnel(self):
730
742
raise socket.error("Tunnel connection failed: %d %s" % (code,
731
743
message.strip()))
732
744
while True:
733
-
line = response.fp.readline()
745
+
line = response.fp.readline(_MAXLINE + 1)
746
+
if len(line) > _MAXLINE:
747
+
raise LineTooLong("header line")
734
748
if line == '\r\n': break
735
749
736
750
@@ -1233,6 +1247,11 @@ def __init__(self, line):
1233
1247
self.args = line,
1234
1248
self.line = line
1235
1249
1250
+
class LineTooLong(HTTPException):
1251
+
def __init__(self, line_type):
1252
+
HTTPException.__init__(self, "got more than %d bytes when reading %s"
1253
+
% (_MAXLINE, line_type))
1254
+
1236
1255
# for backwards compatibility
1237
1256
error = HTTPException
1238
1257
Original file line number Diff line number Diff line change
@@ -319,6 +319,35 @@ def test_filenoattr(self):
319
319
self.assertTrue(hasattr(resp,'fileno'),
320
320
'HTTPResponse should expose a fileno attribute')
321
321
322
+
# Test lines overflowing the max line size (_MAXLINE in http.client)
323
+
324
+
def test_overflowing_status_line(self):
325
+
self.skipTest("disabled for HTTP 0.9 support")
326
+
body = "HTTP/1.1 200 Ok" + "k" * 65536 + "\r\n"
327
+
resp = httplib.HTTPResponse(FakeSocket(body))
328
+
self.assertRaises((httplib.LineTooLong, httplib.BadStatusLine), resp.begin)
329
+
330
+
def test_overflowing_header_line(self):
331
+
body = (
332
+
'HTTP/1.1 200 OK\r\n'
333
+
'X-Foo: bar' + 'r' * 65536 + '\r\n\r\n'
334
+
)
335
+
resp = httplib.HTTPResponse(FakeSocket(body))
336
+
self.assertRaises(httplib.LineTooLong, resp.begin)
337
+
338
+
def test_overflowing_chunked_line(self):
339
+
body = (
340
+
'HTTP/1.1 200 OK\r\n'
341
+
'Transfer-Encoding: chunked\r\n\r\n'
342
+
+ '0' * 65536 + 'a\r\n'
343
+
'hello world\r\n'
344
+
'0\r\n'
345
+
)
346
+
resp = httplib.HTTPResponse(FakeSocket(body))
347
+
resp.begin()
348
+
self.assertRaises(httplib.LineTooLong, resp.read)
349
+
350
+
322
351
class OfflineTest(TestCase):
323
352
def test_responses(self):
324
353
self.assertEqual(httplib.responses[httplib.NOT_FOUND], "Not Found")
Original file line number Diff line number Diff line change
@@ -22,6 +22,9 @@ Core and Builtins
22
22
Library
23
23
-------
24
24
25
+
- Issue #6791: Limit header line length (to 65535 bytes) in http.client,
26
+
to avoid denial of services from the other party.
27
+
25
28
- Issue #10404: Use ctl-button-1 on OSX for the context menu in Idle.
26
29
27
30
- Issue #9907: Fix tab handling on OSX when using editline by calling
You can’t perform that action at this time.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4