@@ -1151,3 +1151,57 @@ async def test_treat_as_secure_origin() -> None:
11511151 assert len (jar ) == 1
11521152 filtered_cookies = jar .filter_cookies (request_url = endpoint )
11531153 assert len (filtered_cookies ) == 1
1154+
1155+
1156+ async def test_filter_cookies_does_not_leak_memory () -> None :
1157+ """Test that filter_cookies doesn't create empty cookie entries.
1158+
1159+ Regression test for https://github.com/aio-libs/aiohttp/issues/11052
1160+ """
1161+ jar = CookieJar ()
1162+
1163+ # Set a cookie with Path=/
1164+ jar .update_cookies ({"test_cookie" : "value; Path=/" }, URL ("http://example.com/" ))
1165+
1166+ # Check initial state
1167+ assert len (jar ) == 1
1168+ initial_storage_size = len (jar ._cookies )
1169+ initial_morsel_cache_size = len (jar ._morsel_cache )
1170+
1171+ # Make multiple requests with different paths
1172+ paths = [
1173+ "/" ,
1174+ "/api" ,
1175+ "/api/v1" ,
1176+ "/api/v1/users" ,
1177+ "/api/v1/users/123" ,
1178+ "/static/css/style.css" ,
1179+ "/images/logo.png" ,
1180+ ]
1181+
1182+ for path in paths :
1183+ url = URL (f"http://example.com{ path } " )
1184+ filtered = jar .filter_cookies (url )
1185+ # Should still get the cookie
1186+ assert len (filtered ) == 1
1187+ assert "test_cookie" in filtered
1188+
1189+ # Storage size should not grow significantly
1190+ # Only the shared cookie entry ('', '') may be added
1191+ final_storage_size = len (jar ._cookies )
1192+ assert final_storage_size <= initial_storage_size + 1
1193+
1194+ # Verify _morsel_cache doesn't leak either
1195+ # It should only have entries for domains/paths where cookies exist
1196+ final_morsel_cache_size = len (jar ._morsel_cache )
1197+ assert final_morsel_cache_size <= initial_morsel_cache_size + 1
1198+
1199+ # Verify no empty entries were created for domain-path combinations
1200+ for key , cookies in jar ._cookies .items ():
1201+ if key != ("" , "" ): # Skip the shared cookie entry
1202+ assert len (cookies ) > 0 , f"Empty cookie entry found for { key } "
1203+
1204+ # Verify _morsel_cache entries correspond to actual cookies
1205+ for key , morsels in jar ._morsel_cache .items ():
1206+ assert key in jar ._cookies , f"Orphaned morsel cache entry for { key } "
1207+ assert len (morsels ) > 0 , f"Empty morsel cache entry found for { key } "
0 commit comments