]> granicus.if.org Git - python/commitdiff
#900744: If an invalid chunked-encoding header is sent by a server,
authorGeorg Brandl <georg@python.org>
Sun, 24 Feb 2008 00:03:22 +0000 (00:03 +0000)
committerGeorg Brandl <georg@python.org>
Sun, 24 Feb 2008 00:03:22 +0000 (00:03 +0000)
httplib will now raise IncompleteRead and close the connection instead
of raising ValueError.

Lib/httplib.py
Lib/test/test_httplib.py
Misc/NEWS

index c7d8e781df06212bfc62682f11ce513adf3a5444..bb4b59e70116fb6df97590ed648d9ae8433e17f6 100644 (file)
@@ -546,7 +546,13 @@ class HTTPResponse:
                 i = line.find(';')
                 if i >= 0:
                     line = line[:i] # strip chunk-extensions
-                chunk_left = int(line, 16)
+                try:
+                    chunk_left = int(line, 16)
+                except ValueError:
+                    # close the connection as protocol synchronisation is
+                    # probably lost
+                    self.close()
+                    raise IncompleteRead(value)
                 if chunk_left == 0:
                     break
             if amt is None:
index d312ae5fa95ab4485b60129f0cc89c01810b018b..e9dd9d66c34fcb67b40e95ac31303d1d435e1a90 100644 (file)
@@ -156,6 +156,35 @@ class BasicTest(TestCase):
         conn.request('GET', '/foo', body)
         self.assertTrue(sock.data.startswith(expected))
 
+    def test_chunked(self):
+        chunked_start = (
+            'HTTP/1.1 200 OK\r\n'
+            'Transfer-Encoding: chunked\r\n\r\n'
+            'a\r\n'
+            'hello worl\r\n'
+            '1\r\n'
+            'd\r\n'
+        )
+        sock = FakeSocket(chunked_start + '0\r\n')
+        resp = httplib.HTTPResponse(sock, method="GET")
+        resp.begin()
+        self.assertEquals(resp.read(), 'hello world')
+        resp.close()
+
+        for x in ('', 'foo\r\n'):
+            sock = FakeSocket(chunked_start + x)
+            resp = httplib.HTTPResponse(sock, method="GET")
+            resp.begin()
+            try:
+                resp.read()
+            except httplib.IncompleteRead, i:
+                self.assertEquals(i.partial, 'hello world')
+            else:
+                self.fail('IncompleteRead expected')
+            finally:
+                resp.close()
+
+
 class OfflineTest(TestCase):
     def test_responses(self):
         self.assertEquals(httplib.responses[httplib.NOT_FOUND], "Not Found")
index cac693286dc1a861c1ce62f0f14f0e44187cfc64..9d9264e0e30df363fc780610709052d0438280bd 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -441,6 +441,10 @@ Core and builtins
 Library
 -------
 
+- #900744: If an invalid chunked-encoding header is sent by a server,
+  httplib will now raise IncompleteRead and close the connection instead
+  of raising ValueError.
+
 - #1492: The content type of BaseHTTPServer error messages can now be
   overridden.