Skip to content

Commit aae7b43

Browse files
gh-100001: Also escape \s in http.server log messages. (GH-100038)
Also \ escape \s in the http.server BaseHTTPRequestHandler.log_message so that it is technically possible to parse the line and reconstruct what the original data was. Without this a \xHH is ambiguious as to if it is a hex replacement we put in or the characters r"\x" came through in the original request line. (cherry picked from commit 7e29398) Co-authored-by: Gregory P. Smith <[email protected]>
1 parent ec8c06b commit aae7b43

File tree

3 files changed

+8
-0
lines changed

3 files changed

+8
-0
lines changed

Lib/http/server.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -567,6 +567,7 @@ def log_error(self, format, *args):
567567
# https://en.wikipedia.org/wiki/List_of_Unicode_characters#Control_codes
568568
_control_char_table = str.maketrans(
569569
{c: fr'\x{c:02x}' for c in itertools.chain(range(0x20), range(0x7f,0xa0))})
570+
_control_char_table[ord('\\')] = r'\\'
570571

571572
def log_message(self, format, *args):
572573
"""Log an arbitrary message.

Lib/test/test_httpservers.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -994,6 +994,7 @@ def test_unprintable_not_logged(self):
994994
log_message(self.handler, '/\033bar\000\033')
995995
log_message(self.handler, '/spam %s.', 'a')
996996
log_message(self.handler, '/spam %s.', '\033\x7f\x9f\xa0beans')
997+
log_message(self.handler, '"GET /foo\\b"ar\007 HTTP/1.0"')
997998
stderr = fake_stderr.getvalue()
998999
self.assertNotIn('\033', stderr) # non-printable chars are caught.
9991000
self.assertNotIn('\000', stderr) # non-printable chars are caught.
@@ -1002,6 +1003,7 @@ def test_unprintable_not_logged(self):
10021003
self.assertIn(r'/\x1bbar\x00\x1b', lines[1])
10031004
self.assertIn('/spam a.', lines[2])
10041005
self.assertIn('/spam \\x1b\\x7f\\x9f\xa0beans.', lines[3])
1006+
self.assertIn(r'"GET /foo\\b"ar\x07 HTTP/1.0"', lines[4])
10051007

10061008
def test_http_1_1(self):
10071009
result = self.send_typical_request(b'GET / HTTP/1.1\r\n\r\n')
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Also \ escape \s in the http.server BaseHTTPRequestHandler.log_message so
2+
that it is technically possible to parse the line and reconstruct what the
3+
original data was. Without this a \xHH is ambiguious as to if it is a hex
4+
replacement we put in or the characters r"\x" came through in the original
5+
request line.

0 commit comments

Comments
 (0)