Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit b79b5c0

Browse files
matthewbelisle-wfmiss-islington
authored andcommitted
bpo-35028: cgi: Fix max_num_fields off by one error (GH-9973)
https://bugs.python.org/issue35028
1 parent b7d6205 commit b79b5c0

2 files changed

Lines changed: 24 additions & 18 deletions

File tree

Lib/cgi.py

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -618,6 +618,11 @@ def read_multi(self, environ, keep_blank_values, strict_parsing):
618618
first_line = self.fp.readline()
619619
self.bytes_read += len(first_line)
620620

621+
# Propagate max_num_fields into the sub class appropriately
622+
max_num_fields = self.max_num_fields
623+
if max_num_fields is not None:
624+
max_num_fields -= len(self.list)
625+
621626
while True:
622627
parser = FeedParser()
623628
hdr_text = b""
@@ -637,23 +642,19 @@ def read_multi(self, environ, keep_blank_values, strict_parsing):
637642
if 'content-length' in headers:
638643
del headers['content-length']
639644

640-
# Propagate max_num_fields into the sub class appropriately
641-
sub_max_num_fields = self.max_num_fields
642-
if sub_max_num_fields is not None:
643-
sub_max_num_fields -= len(self.list)
644-
645645
part = klass(self.fp, headers, ib, environ, keep_blank_values,
646646
strict_parsing,self.limit-self.bytes_read,
647-
self.encoding, self.errors, sub_max_num_fields)
647+
self.encoding, self.errors, max_num_fields)
648648

649-
max_num_fields = self.max_num_fields
650-
if max_num_fields is not None and part.list:
651-
max_num_fields -= len(part.list)
649+
if max_num_fields is not None:
650+
max_num_fields -= 1
651+
if part.list:
652+
max_num_fields -= len(part.list)
653+
if max_num_fields < 0:
654+
raise ValueError('Max number of fields exceeded')
652655

653656
self.bytes_read += part.bytes_read
654657
self.list.append(part)
655-
if max_num_fields is not None and max_num_fields < len(self.list):
656-
raise ValueError('Max number of fields exceeded')
657658
if part.done or self.bytes_read >= self.length > 0:
658659
break
659660
self.skip_lines()

Lib/test/test_cgi.py

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -401,33 +401,38 @@ def test_max_num_fields(self):
401401
data = """---123
402402
Content-Disposition: form-data; name="a"
403403
404-
a
404+
3
405405
---123
406406
Content-Type: application/x-www-form-urlencoded
407407
408-
a=a&a=a
408+
a=4
409+
---123
410+
Content-Type: application/x-www-form-urlencoded
411+
412+
a=5
409413
---123--
410414
"""
411415
environ = {
412416
'CONTENT_LENGTH': str(len(data)),
413417
'CONTENT_TYPE': 'multipart/form-data; boundary=-123',
414-
'QUERY_STRING': 'a=a&a=a',
418+
'QUERY_STRING': 'a=1&a=2',
415419
'REQUEST_METHOD': 'POST',
416420
}
417421

418422
# 2 GET entities
419-
# 2 top level POST entities
420-
# 2 entities within the second POST entity
423+
# 1 top level POST entities
424+
# 1 entity within the second POST entity
425+
# 1 entity within the third POST entity
421426
with self.assertRaises(ValueError):
422427
cgi.FieldStorage(
423428
fp=BytesIO(data.encode()),
424429
environ=environ,
425-
max_num_fields=5,
430+
max_num_fields=4,
426431
)
427432
cgi.FieldStorage(
428433
fp=BytesIO(data.encode()),
429434
environ=environ,
430-
max_num_fields=6,
435+
max_num_fields=5,
431436
)
432437

433438
def testQSAndFormData(self):

0 commit comments

Comments
 (0)