From 53476dfd4ef4fb1bb74a267714bbc39eda71b403 Mon Sep 17 00:00:00 2001
From: Sam Bull <git@sambull.org>
Date: Mon, 13 Nov 2023 22:36:04 +0000
Subject: [PATCH] Disallow arbitrary sequence types in version (#7835) (#7836)

--- python-aiohttp-3.8.4.orig/aiohttp/client_reqrep.py
+++ python-aiohttp-3.8.4/aiohttp/client_reqrep.py
@@ -664,8 +664,8 @@ class ClientRequest:
             self.headers[hdrs.CONNECTION] = connection
 
         # status + headers
-        status_line = "{0} {1} HTTP/{2[0]}.{2[1]}".format(
-            self.method, path, self.version
+        status_line = "{0} {1} HTTP/{v.major}.{v.minor}".format(
+            self.method, path, v=self.version
         )
         await writer.write_headers(status_line, self.headers)
 
--- python-aiohttp-3.8.4.orig/tests/test_client_request.py
+++ python-aiohttp-3.8.4/tests/test_client_request.py
@@ -20,6 +20,7 @@ from aiohttp.client_reqrep import (
     _merge_ssl_params,
 )
 from aiohttp.helpers import PY_311
+from aiohttp.http import HttpVersion
 from aiohttp.test_utils import make_mocked_coro
 
 
@@ -575,18 +576,18 @@ async def test_connection_header(loop, c
     req.headers.clear()
 
     req.keep_alive.return_value = True
-    req.version = (1, 1)
+    req.version = HttpVersion(1, 1)
     req.headers.clear()
     await req.send(conn)
     assert req.headers.get("CONNECTION") is None
 
-    req.version = (1, 0)
+    req.version = HttpVersion(1, 0)
     req.headers.clear()
     await req.send(conn)
     assert req.headers.get("CONNECTION") == "keep-alive"
 
     req.keep_alive.return_value = False
-    req.version = (1, 1)
+    req.version = HttpVersion(1, 1)
     req.headers.clear()
     await req.send(conn)
     assert req.headers.get("CONNECTION") == "close"
@@ -1113,6 +1114,19 @@ async def test_close(loop, buf, conn) ->
     resp.close()
 
 
+async def test_bad_version(loop, conn) -> None:
+    req = ClientRequest(
+        "GET",
+        URL("http://python.org"),
+        loop=loop,
+        headers={"Connection": "Close"},
+        version=("1", "1\r\nInjected-Header: not allowed"),
+    )
+
+    with pytest.raises(AttributeError):
+        await req.send(conn)
+
+
 async def test_custom_response_class(loop, conn) -> None:
     class CustomResponse(ClientResponse):
         def read(self, decode=False):
