Skip to content

Commit e90af45

Browse files
authored
Avoid infinite loop in HTTPResponse.read_chunked when amt=0 (#4974)
1 parent 67ed74f commit e90af45

3 files changed

Lines changed: 14 additions & 2 deletions

File tree

‎changelog/3793.bugfix.rst‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
Fixed ``HTTPResponse.stream()`` to handle ``amt=0``.
1+
Fixed ``HTTPResponse.stream()`` and ``HTTPResponse.read_chunked()`` to handle ``amt=0``.

‎src/urllib3/response.py‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1410,7 +1410,9 @@ def read_chunked(
14101410
if self._fp.fp is None: # type: ignore[union-attr]
14111411
return None
14121412

1413-
if amt and amt < 0:
1413+
if amt == 0:
1414+
return
1415+
elif amt and amt < 0:
14141416
# Negative numbers and `None` should be treated the same,
14151417
# but httplib handles only `None` correctly.
14161418
amt = None

‎test/test_response.py‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1503,6 +1503,16 @@ def test_stream_zero_amt(self) -> None:
15031503
data = list(resp.stream(0))
15041504
assert data == []
15051505

1506+
def test_read_chunked_zero_amt(self) -> None:
1507+
r = httplib.HTTPResponse(MockSock) # type: ignore[arg-type]
1508+
r.fp = MockChunkedEncodingResponse([b"hello"]) # type: ignore[assignment]
1509+
r.chunked = True
1510+
r.chunk_left = None
1511+
resp = HTTPResponse(
1512+
r, preload_content=False, headers={"transfer-encoding": "chunked"}
1513+
)
1514+
assert len(list(resp.read_chunked(0))) == 0
1515+
15061516
@pytest.mark.parametrize(
15071517
"preload_content, amt, read_meth",
15081518
[

0 commit comments

Comments
 (0)