[Python-checkins] bpo-35028: cgi: Fix max_num_fields off by one error (GH-9973)

Miss Islington (bot) webhook-mailer at python.org
Tue Oct 23 06:54:55 EDT 2018


https://github.com/python/cpython/commit/178bf58e798d3ef63f18b314056efbc3c33dd48b
commit: 178bf58e798d3ef63f18b314056efbc3c33dd48b
branch: 3.7
author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
committer: GitHub <noreply at github.com>
date: 2018-10-23T03:54:52-07:00
summary:

bpo-35028: cgi: Fix max_num_fields off by one error (GH-9973)


https://bugs.python.org/issue35028
(cherry picked from commit b79b5c09493e98374e48fa122d82dab528fc6e72)

Co-authored-by: matthewbelisle-wf <matthew.belisle at workiva.com>

files:
M Lib/cgi.py
M Lib/test/test_cgi.py

diff --git a/Lib/cgi.py b/Lib/cgi.py
index da4a34672c5e..8cf668718ded 100755
--- a/Lib/cgi.py
+++ b/Lib/cgi.py
@@ -635,6 +635,11 @@ def read_multi(self, environ, keep_blank_values, strict_parsing):
             first_line = self.fp.readline()
             self.bytes_read += len(first_line)
 
+        # Propagate max_num_fields into the sub class appropriately
+        max_num_fields = self.max_num_fields
+        if max_num_fields is not None:
+            max_num_fields -= len(self.list)
+
         while True:
             parser = FeedParser()
             hdr_text = b""
@@ -654,23 +659,19 @@ def read_multi(self, environ, keep_blank_values, strict_parsing):
             if 'content-length' in headers:
                 del headers['content-length']
 
-            # Propagate max_num_fields into the sub class appropriately
-            sub_max_num_fields = self.max_num_fields
-            if sub_max_num_fields is not None:
-                sub_max_num_fields -= len(self.list)
-
             part = klass(self.fp, headers, ib, environ, keep_blank_values,
                          strict_parsing,self.limit-self.bytes_read,
-                         self.encoding, self.errors, sub_max_num_fields)
+                         self.encoding, self.errors, max_num_fields)
 
-            max_num_fields = self.max_num_fields
-            if max_num_fields is not None and part.list:
-                max_num_fields -= len(part.list)
+            if max_num_fields is not None:
+                max_num_fields -= 1
+                if part.list:
+                    max_num_fields -= len(part.list)
+                if max_num_fields < 0:
+                    raise ValueError('Max number of fields exceeded')
 
             self.bytes_read += part.bytes_read
             self.list.append(part)
-            if max_num_fields is not None and max_num_fields < len(self.list):
-                raise ValueError('Max number of fields exceeded')
             if part.done or self.bytes_read >= self.length > 0:
                 break
         self.skip_lines()
diff --git a/Lib/test/test_cgi.py b/Lib/test/test_cgi.py
index ff9c005518e0..f4e00c7a72c5 100644
--- a/Lib/test/test_cgi.py
+++ b/Lib/test/test_cgi.py
@@ -411,33 +411,38 @@ def test_max_num_fields(self):
         data = """---123
 Content-Disposition: form-data; name="a"
 
-a
+3
 ---123
 Content-Type: application/x-www-form-urlencoded
 
-a=a&a=a
+a=4
+---123
+Content-Type: application/x-www-form-urlencoded
+
+a=5
 ---123--
 """
         environ = {
             'CONTENT_LENGTH':   str(len(data)),
             'CONTENT_TYPE':     'multipart/form-data; boundary=-123',
-            'QUERY_STRING':     'a=a&a=a',
+            'QUERY_STRING':     'a=1&a=2',
             'REQUEST_METHOD':   'POST',
         }
 
         # 2 GET entities
-        # 2 top level POST entities
-        # 2 entities within the second POST entity
+        # 1 top level POST entities
+        # 1 entity within the second POST entity
+        # 1 entity within the third POST entity
         with self.assertRaises(ValueError):
             cgi.FieldStorage(
                 fp=BytesIO(data.encode()),
                 environ=environ,
-                max_num_fields=5,
+                max_num_fields=4,
             )
         cgi.FieldStorage(
             fp=BytesIO(data.encode()),
             environ=environ,
-            max_num_fields=6,
+            max_num_fields=5,
         )
 
     def testQSAndFormData(self):



More information about the Python-checkins mailing list