@@ -1747,6 +1747,36 @@ async def test_parse_chunked_payload_size_error(
17471747 p .feed_data (b"blah\r \n " )
17481748 assert isinstance (out .exception (), http_exceptions .TransferEncodingError )
17491749
1750+ async def test_parse_chunked_payload_size_data_mismatch (
1751+ self , protocol : BaseProtocol
1752+ ) -> None :
1753+ """Chunk-size does not match actual data: should raise, not hang.
1754+
1755+ Regression test for #10596.
1756+ """
1757+ out = aiohttp .StreamReader (protocol , 2 ** 16 , loop = asyncio .get_running_loop ())
1758+ p = HttpPayloadParser (out , chunked = True , headers_parser = HeadersParser ())
1759+ # Declared chunk-size is 4 but actual data is "Hello" (5 bytes).
1760+ # After consuming 4 bytes, remaining starts with "o" not "\r\n".
1761+ with pytest .raises (http_exceptions .TransferEncodingError ):
1762+ p .feed_data (b"4\r \n Hello\r \n 0\r \n \r \n " )
1763+ assert isinstance (out .exception (), http_exceptions .TransferEncodingError )
1764+
1765+ async def test_parse_chunked_payload_size_data_mismatch_too_short (
1766+ self , protocol : BaseProtocol
1767+ ) -> None :
1768+ """Chunk-size larger than data: declared 6 but only 5 bytes before CRLF.
1769+
1770+ Regression test for #10596.
1771+ """
1772+ out = aiohttp .StreamReader (protocol , 2 ** 16 , loop = asyncio .get_running_loop ())
1773+ p = HttpPayloadParser (out , chunked = True , headers_parser = HeadersParser ())
1774+ # Declared chunk-size is 6 but actual data before CRLF is "Hello" (5 bytes).
1775+ # Parser reads 6 bytes: "Hello\r", then expects \r\n but sees "\n0\r\n..."
1776+ with pytest .raises (http_exceptions .TransferEncodingError ):
1777+ p .feed_data (b"6\r \n Hello\r \n 0\r \n \r \n " )
1778+ assert isinstance (out .exception (), http_exceptions .TransferEncodingError )
1779+
17501780 async def test_parse_chunked_payload_split_end (
17511781 self , protocol : BaseProtocol
17521782 ) -> None :
0 commit comments