@@ -1127,3 +1127,57 @@ async def test_treat_as_secure_origin() -> None:
11271127 assert len (jar ) == 1
11281128 filtered_cookies = jar .filter_cookies (request_url = endpoint )
11291129 assert len (filtered_cookies ) == 1
1130+
1131+
1132+ async def test_filter_cookies_does_not_leak_memory () -> None :
1133+ """Test that filter_cookies doesn't create empty cookie entries.
1134+
1135+ Regression test for https://github.com/aio-libs/aiohttp/issues/11052
1136+ """
1137+ jar = CookieJar ()
1138+
1139+ # Set a cookie with Path=/
1140+ jar .update_cookies ({"test_cookie" : "value; Path=/" }, URL ("http://example.com/" ))
1141+
1142+ # Check initial state
1143+ assert len (jar ) == 1
1144+ initial_storage_size = len (jar ._cookies )
1145+ initial_morsel_cache_size = len (jar ._morsel_cache )
1146+
1147+ # Make multiple requests with different paths
1148+ paths = [
1149+ "/" ,
1150+ "/api" ,
1151+ "/api/v1" ,
1152+ "/api/v1/users" ,
1153+ "/api/v1/users/123" ,
1154+ "/static/css/style.css" ,
1155+ "/images/logo.png" ,
1156+ ]
1157+
1158+ for path in paths :
1159+ url = URL (f"http://example.com{ path } " )
1160+ filtered = jar .filter_cookies (url )
1161+ # Should still get the cookie
1162+ assert len (filtered ) == 1
1163+ assert "test_cookie" in filtered
1164+
1165+ # Storage size should not grow significantly
1166+ # Only the shared cookie entry ('', '') may be added
1167+ final_storage_size = len (jar ._cookies )
1168+ assert final_storage_size <= initial_storage_size + 1
1169+
1170+ # Verify _morsel_cache doesn't leak either
1171+ # It should only have entries for domains/paths where cookies exist
1172+ final_morsel_cache_size = len (jar ._morsel_cache )
1173+ assert final_morsel_cache_size <= initial_morsel_cache_size + 1
1174+
1175+ # Verify no empty entries were created for domain-path combinations
1176+ for key , cookies in jar ._cookies .items ():
1177+ if key != ("" , "" ): # Skip the shared cookie entry
1178+ assert len (cookies ) > 0 , f"Empty cookie entry found for { key } "
1179+
1180+ # Verify _morsel_cache entries correspond to actual cookies
1181+ for key , morsels in jar ._morsel_cache .items ():
1182+ assert key in jar ._cookies , f"Orphaned morsel cache entry for { key } "
1183+ assert len (morsels ) > 0 , f"Empty morsel cache entry found for { key } "
0 commit comments