Skip to content

Commit b630ca7

Browse files
[3.9] bpo-5054: CGIHTTPRequestHandler.run_cgi() HTTP_ACCEPT improperly parsed (GH-23638) (GH-23657)
(cherry picked from commit da3d2ab) Co-authored-by: Senthil Kumaran <[email protected]> Automerge-Triggered-By: GH:orsenthil
1 parent 06002b3 commit b630ca7

File tree

3 files changed

+41
-8
lines changed

3 files changed

+41
-8
lines changed

Lib/http/server.py

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1123,12 +1123,7 @@ def run_cgi(self):
11231123
referer = self.headers.get('referer')
11241124
if referer:
11251125
env['HTTP_REFERER'] = referer
1126-
accept = []
1127-
for line in self.headers.getallmatchingheaders('accept'):
1128-
if line[:1] in "\t\n\r ":
1129-
accept.append(line.strip())
1130-
else:
1131-
accept = accept + line[7:].split(',')
1126+
accept = self.headers.get_all('accept', ())
11321127
env['HTTP_ACCEPT'] = ','.join(accept)
11331128
ua = self.headers.get('user-agent')
11341129
if ua:

Lib/test/test_httpservers.py

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
Written by Cody A.W. Somerville <[email protected]>,
44
Josip Dzolonga, and Michael Otteneder for the 2007/08 GHOP contest.
55
"""
6-
6+
from collections import OrderedDict
77
from http.server import BaseHTTPRequestHandler, HTTPServer, \
88
SimpleHTTPRequestHandler, CGIHTTPRequestHandler
99
from http import server, HTTPStatus
@@ -19,7 +19,7 @@
1919
import email.message
2020
import email.utils
2121
import html
22-
import http.client
22+
import http, http.client
2323
import urllib.parse
2424
import tempfile
2525
import time
@@ -586,6 +586,15 @@ def test_html_escape_filename(self):
586586
print(os.environ["%s"])
587587
"""
588588

589+
cgi_file6 = """\
590+
#!%s
591+
import os
592+
593+
print("Content-type: text/plain")
594+
print()
595+
print(repr(os.environ))
596+
"""
597+
589598

590599
@unittest.skipIf(hasattr(os, 'geteuid') and os.geteuid() == 0,
591600
"This test can't be run reliably as root (issue #13308).")
@@ -664,6 +673,11 @@ def setUp(self):
664673
file5.write(cgi_file1 % self.pythonexe)
665674
os.chmod(self.file5_path, 0o777)
666675

676+
self.file6_path = os.path.join(self.cgi_dir, 'file6.py')
677+
with open(self.file6_path, 'w', encoding='utf-8') as file6:
678+
file6.write(cgi_file6 % self.pythonexe)
679+
os.chmod(self.file6_path, 0o777)
680+
667681
os.chdir(self.parent_dir)
668682

669683
def tearDown(self):
@@ -683,6 +697,8 @@ def tearDown(self):
683697
os.remove(self.file4_path)
684698
if self.file5_path:
685699
os.remove(self.file5_path)
700+
if self.file6_path:
701+
os.remove(self.file6_path)
686702
os.rmdir(self.cgi_child_dir)
687703
os.rmdir(self.cgi_dir)
688704
os.rmdir(self.cgi_dir_in_sub_dir)
@@ -816,6 +832,23 @@ def test_cgi_path_in_sub_directories(self):
816832
finally:
817833
CGIHTTPRequestHandler.cgi_directories.remove('/sub/dir/cgi-bin')
818834

835+
def test_accept(self):
836+
browser_accept = \
837+
'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'
838+
tests = (
839+
((('Accept', browser_accept),), browser_accept),
840+
((), ''),
841+
# Hack case to get two values for the one header
842+
((('Accept', 'text/html'), ('ACCEPT', 'text/plain')),
843+
'text/html,text/plain'),
844+
)
845+
for headers, expected in tests:
846+
headers = OrderedDict(headers)
847+
with self.subTest(headers):
848+
res = self.request('/cgi-bin/file6.py', 'GET', headers=headers)
849+
self.assertEqual(http.HTTPStatus.OK, res.status)
850+
expected = f"'HTTP_ACCEPT': {expected!r}"
851+
self.assertIn(expected.encode('ascii'), res.read())
819852

820853

821854
class SocketlessRequestHandler(SimpleHTTPRequestHandler):
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
CGIHTTPRequestHandler.run_cgi() HTTP_ACCEPT improperly parsed. Replace the
2+
special purpose getallmatchingheaders with generic get_all method and add
3+
relevant tests.
4+
5+
Original Patch by Martin Panter. Modified by Senthil Kumaran.

0 commit comments

Comments
 (0)