[Python-checkins] cpython (2.7): simply ignore headers with no name (#19996)

benjamin.peterson python-checkins at python.org
Mon Jan 26 05:35:21 CET 2015


https://hg.python.org/cpython/rev/9a4882b12218
changeset:   94284:9a4882b12218
branch:      2.7
parent:      94275:5db28a3199b2
user:        Benjamin Peterson <benjamin at python.org>
date:        Sun Jan 25 23:34:42 2015 -0500
summary:
  simply ignore headers with no name (#19996)

Patch by Cory Benfield.

files:
  Lib/httplib.py           |   5 +++++
  Lib/rfc822.py            |   7 ++++++-
  Lib/test/test_httplib.py |  10 ++++++++++
  Lib/test/test_rfc822.py  |   6 ++++++
  Misc/NEWS                |   3 +++
  5 files changed, 30 insertions(+), 1 deletions(-)


diff --git a/Lib/httplib.py b/Lib/httplib.py
--- a/Lib/httplib.py
+++ b/Lib/httplib.py
@@ -313,6 +313,11 @@
                 hlist.append(line)
                 self.addheader(headerseen, line[len(headerseen)+1:].strip())
                 continue
+            elif headerseen is not None:
+                # An empty header name. These aren't allowed in HTTP, but it's
+                # probably a benign mistake. Don't add the header, just keep
+                # going.
+                continue
             else:
                 # It's not a header line; throw it back and stop here.
                 if not self.dict:
diff --git a/Lib/rfc822.py b/Lib/rfc822.py
--- a/Lib/rfc822.py
+++ b/Lib/rfc822.py
@@ -179,6 +179,11 @@
                 lst.append(line)
                 self.dict[headerseen] = line[len(headerseen)+1:].strip()
                 continue
+            elif headerseen is not None:
+                # An empty header name. These aren't allowed in HTTP, but it's
+                # probably a benign mistake. Don't add the header, just keep
+                # going.
+                continue
             else:
                 # It's not a header line; throw it back and stop here.
                 if not self.dict:
@@ -202,7 +207,7 @@
         data in RFC 2822-like formats with special header formats.
         """
         i = line.find(':')
-        if i > 0:
+        if i > -1:
             return line[:i].lower()
         return None
 
diff --git a/Lib/test/test_httplib.py b/Lib/test/test_httplib.py
--- a/Lib/test/test_httplib.py
+++ b/Lib/test/test_httplib.py
@@ -164,6 +164,16 @@
         conn.request('GET', '/foo')
         self.assertTrue(sock.data.startswith(expected))
 
+    def test_malformed_headers_coped_with(self):
+        # Issue 19996
+        body = "HTTP/1.1 200 OK\r\nFirst: val\r\n: nval\r\nSecond: val\r\n\r\n"
+        sock = FakeSocket(body)
+        resp = httplib.HTTPResponse(sock)
+        resp.begin()
+
+        self.assertEqual(resp.getheader('First'), 'val')
+        self.assertEqual(resp.getheader('Second'), 'val')
+
 
 class BasicTest(TestCase):
     def test_status_lines(self):
diff --git a/Lib/test/test_rfc822.py b/Lib/test/test_rfc822.py
--- a/Lib/test/test_rfc822.py
+++ b/Lib/test/test_rfc822.py
@@ -248,6 +248,12 @@
         eq(rfc822.quote('foo\\wacky"name'), 'foo\\\\wacky\\"name')
         eq(rfc822.unquote('"foo\\\\wacky\\"name"'), 'foo\\wacky"name')
 
+    def test_invalid_headers(self):
+        eq = self.assertEqual
+        msg = self.create_message("First: val\n: otherval\nSecond: val2\n")
+        eq(msg.getheader('First'), 'val')
+        eq(msg.getheader('Second'), 'val2')
+
 
 def test_main():
     test_support.run_unittest(MessageTestCase)
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -15,6 +15,9 @@
 Library
 -------
 
+- Issue #19996: Make :mod:`httplib` ignore headers with no name rather than
+  assuming the body has started.
+
 - Issue #20188: Support Application-Layer Protocol Negotiation (ALPN) in the ssl
   module.
 

-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list