@@ -1698,6 +1698,36 @@ async def test_parse_chunked_payload_size_error(
16981698 p .feed_data (b"blah\r \n " )
16991699 assert isinstance (out .exception (), http_exceptions .TransferEncodingError )
17001700
1701+ async def test_parse_chunked_payload_size_data_mismatch (
1702+ self , protocol : BaseProtocol
1703+ ) -> None :
1704+ """Chunk-size does not match actual data: should raise, not hang.
1705+
1706+ Regression test for #10596.
1707+ """
1708+ out = aiohttp .StreamReader (protocol , 2 ** 16 , loop = asyncio .get_running_loop ())
1709+ p = HttpPayloadParser (out , chunked = True , headers_parser = HeadersParser ())
1710+ # Declared chunk-size is 4 but actual data is "Hello" (5 bytes).
1711+ # After consuming 4 bytes, remaining starts with "o" not "\r\n".
1712+ with pytest .raises (http_exceptions .TransferEncodingError ):
1713+ p .feed_data (b"4\r \n Hello\r \n 0\r \n \r \n " )
1714+ assert isinstance (out .exception (), http_exceptions .TransferEncodingError )
1715+
1716+ async def test_parse_chunked_payload_size_data_mismatch_too_short (
1717+ self , protocol : BaseProtocol
1718+ ) -> None :
1719+ """Chunk-size larger than data: declared 6 but only 5 bytes before CRLF.
1720+
1721+ Regression test for #10596.
1722+ """
1723+ out = aiohttp .StreamReader (protocol , 2 ** 16 , loop = asyncio .get_running_loop ())
1724+ p = HttpPayloadParser (out , chunked = True , headers_parser = HeadersParser ())
1725+ # Declared chunk-size is 6 but actual data before CRLF is "Hello" (5 bytes).
1726+ # Parser reads 6 bytes: "Hello\r", then expects \r\n but sees "\n0\r\n..."
1727+ with pytest .raises (http_exceptions .TransferEncodingError ):
1728+ p .feed_data (b"6\r \n Hello\r \n 0\r \n \r \n " )
1729+ assert isinstance (out .exception (), http_exceptions .TransferEncodingError )
1730+
17011731 async def test_parse_chunked_payload_split_end (
17021732 self , protocol : BaseProtocol
17031733 ) -> None :
0 commit comments