An interpreted, interactive, object-oriented programming language
CentOS Sources
2017-08-01 71084d584ff953f5463757ec6536406320560b4d
commit | author | age
f63228 1
CS 2 # HG changeset patch
3 # User Benjamin Peterson <benjamin@python.org>
4 # Date 1417827918 18000
5 # Node ID 923aac88a3cc76a95d5a04d9d3ece245147a8064
6 # Parent  339f877cca115c1901f5dd93d7bc066031d2a669
7 smtplib: limit amount read from the network (closes #16042)
8
9 diff --git a/Lib/smtplib.py b/Lib/smtplib.py
10 --- a/Lib/smtplib.py
11 +++ b/Lib/smtplib.py
12 @@ -57,6 +57,7 @@ from sys import stderr
13  SMTP_PORT = 25
14  SMTP_SSL_PORT = 465
15  CRLF = "\r\n"
16 +_MAXLINE = 8192 # more than 8 times larger than RFC 821, 4.5.3
17  
18  OLDSTYLE_AUTH = re.compile(r"auth=(.*)", re.I)
19  
20 @@ -179,10 +180,14 @@ else:
21          def __init__(self, sslobj):
22              self.sslobj = sslobj
23  
24 -        def readline(self):
25 +        def readline(self, size=-1):
26 +            if size < 0:
27 +                size = None
28              str = ""
29              chr = None
30              while chr != "\n":
31 +                if size is not None and len(str) >= size:
32 +                    break
33                  chr = self.sslobj.read(1)
34                  if not chr:
35                      break
36 @@ -353,7 +358,7 @@ class SMTP:
37              self.file = self.sock.makefile('rb')
38          while 1:
39              try:
40 -                line = self.file.readline()
41 +                line = self.file.readline(_MAXLINE + 1)
42              except socket.error as e:
43                  self.close()
44                  raise SMTPServerDisconnected("Connection unexpectedly closed: "
45 @@ -363,6 +368,8 @@ class SMTP:
46                  raise SMTPServerDisconnected("Connection unexpectedly closed")
47              if self.debuglevel > 0:
48                  print>>stderr, 'reply:', repr(line)
49 +            if len(line) > _MAXLINE:
50 +                raise SMTPResponseException(500, "Line too long.")
51              resp.append(line[4:].strip())
52              code = line[:3]
53              # Check that the error code is syntactically correct.
54 diff --git a/Lib/test/test_smtplib.py b/Lib/test/test_smtplib.py
55 --- a/Lib/test/test_smtplib.py
56 +++ b/Lib/test/test_smtplib.py
57 @@ -292,6 +292,33 @@ class BadHELOServerTests(unittest.TestCa
58                              HOST, self.port, 'localhost', 3)
59  
60  
61 +@unittest.skipUnless(threading, 'Threading required for this test.')
62 +class TooLongLineTests(unittest.TestCase):
63 +    respdata = '250 OK' + ('.' * smtplib._MAXLINE * 2) + '\n'
64 +
65 +    def setUp(self):
66 +        self.old_stdout = sys.stdout
67 +        self.output = StringIO.StringIO()
68 +        sys.stdout = self.output
69 +
70 +        self.evt = threading.Event()
71 +        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
72 +        self.sock.settimeout(15)
73 +        self.port = test_support.bind_port(self.sock)
74 +        servargs = (self.evt, self.respdata, self.sock)
75 +        threading.Thread(target=server, args=servargs).start()
76 +        self.evt.wait()
77 +        self.evt.clear()
78 +
79 +    def tearDown(self):
80 +        self.evt.wait()
81 +        sys.stdout = self.old_stdout
82 +
83 +    def testLineTooLong(self):
84 +        self.assertRaises(smtplib.SMTPResponseException, smtplib.SMTP,
85 +                          HOST, self.port, 'localhost', 3)
86 +
87 +
88  sim_users = {'Mr.A@somewhere.com':'John A',
89               'Ms.B@somewhere.com':'Sally B',
90               'Mrs.C@somewhereesle.com':'Ruth C',
91 @@ -526,7 +553,8 @@ class SMTPSimTests(unittest.TestCase):
92  def test_main(verbose=None):
93      test_support.run_unittest(GeneralTests, DebuggingServerTests,
94                                NonConnectingTests,
95 -                              BadHELOServerTests, SMTPSimTests)
96 +                              BadHELOServerTests, SMTPSimTests,
97 +                              TooLongLineTests)
98  
99  if __name__ == '__main__':
100      test_main()