Visitar URL original
gh-150751: validate http.client Content-Length and chunk-size by metsw24-max · Pull Request #150752 · python/cpython · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Shorten the grammar comment and only rstrip the chunk-size line
  • Loading branch information
metsw24-max committed Oct 7, 2026
commit 9a1b068ec9891441629ff54f8a7538e7b51a1d3e
8 changes: 3 additions & 5 deletions Lib/http/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,10 +158,8 @@
# to prevent http header injection.
_contains_disallowed_method_pchar_re = re.compile('[\x00-\x1f]')

# RFC 9112: Content-Length = 1*DIGIT and chunk-size = 1*HEXDIG. int() is more
# permissive (it accepts a leading sign, underscores, surrounding whitespace
# and, in base 16, an "0x" prefix and non-ASCII digits), so the body-framing
# values are matched against the grammar before being passed to int().
# RFC 9112: Content-Length = 1*DIGIT and chunk-size = 1*HEXDIG.
# int() is more permissive, so we match against the grammar before calling it.
_is_legal_content_length = re.compile(r'[0-9]+').fullmatch
_is_legal_chunk_size = re.compile(rb'[0-9a-fA-F]+').fullmatch

Expand Down Expand Up @@ -551,7 +549,7 @@ def _read_next_chunk_size(self):
i = line.find(b";")
if i >= 0:
line = line[:i] # strip chunk-extensions
line = line.strip()
line = line.rstrip()
try:
if not _is_legal_chunk_size(line):
raise ValueError("invalid chunk size")
Expand Down
5 changes: 3 additions & 2 deletions Lib/test/test_httplib.py
Original file line number Diff line number Diff line change
Expand Up @@ -1334,9 +1334,10 @@ def test_malformed_content_length(self):

def test_malformed_chunk_size(self):
# RFC 9112: chunk-size = 1*HEXDIG. Reject sizes that int(_, 16) accepts
# but the grammar forbids (a sign, an "0x" prefix or underscores).
# but the grammar forbids (a sign, an "0x" prefix, underscores or
# leading whitespace).
start = 'HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n'
for size in ('-5', '+5', '0x5', '1_f'):
for size in ('-5', '+5', '0x5', '1_f', ' 5'):
with self.subTest(size=size):
sock = FakeSocket(start + '%s\r\nHELLO\r\n0\r\n\r\n' % size)
resp = client.HTTPResponse(sock, method="GET")
Expand Down
Loading