diff --git a/components/net/cookie_storage.rs b/components/net/cookie_storage.rs index bcedf49b5d3..55b7bc1df2a 100644 --- a/components/net/cookie_storage.rs +++ b/components/net/cookie_storage.rs @@ -8,6 +8,7 @@ use std::cmp::Ordering; use std::collections::HashMap; use std::collections::hash_map::Entry; +use std::net::IpAddr; use std::time::SystemTime; use cookie::Cookie; @@ -292,6 +293,14 @@ impl CookieStorage { } fn reg_host(url: &str) -> String { + let host_for_ip_parse = url + .strip_prefix('[') + .and_then(|url| url.strip_suffix(']')) + .unwrap_or(url); + if let Ok(address) = host_for_ip_parse.parse::() { + return address.to_string().to_lowercase(); + } + reg_suffix(url).to_lowercase() } diff --git a/components/net/tests/cookie.rs b/components/net/tests/cookie.rs index 41fde71279e..9a2546ab469 100644 --- a/components/net/tests/cookie.rs +++ b/components/net/tests/cookie.rs @@ -222,6 +222,36 @@ fn add_cookie_to_storage(storage: &mut CookieStorage, url: &ServoUrl, cookie_str storage.push(cookie, url, source); } +fn assert_ip_cookie_bucket_collision_eviction(ip_a: &str, ip_b: &str) { + let mut storage = CookieStorage::new(5); + let ip_a = ServoUrl::parse(ip_a).unwrap(); + let ip_b = ServoUrl::parse(ip_b).unwrap(); + let source = CookieSource::HTTP; + + for i in 1..=3 { + add_cookie_to_storage(&mut storage, &ip_a, &format!("a{i}=val{i}")); + } + + for i in 1..=5 { + add_cookie_to_storage(&mut storage, &ip_b, &format!("b{i}=val{i}")); + } + + let cookies_a = storage.cookies_for_url(&ip_a, source).unwrap(); + assert_eq!(cookies_a.split("; ").count(), 3); + for i in 1..=3 { + assert!(cookies_a.contains(&format!("a{i}=val{i}"))); + } +} + +#[test] +fn test_ip_cookie_bucket_collision_eviction() { + assert_ip_cookie_bucket_collision_eviction("http://192.168.0.1/path", "http://10.0.0.1/path"); + assert_ip_cookie_bucket_collision_eviction( + "http://[2001:db8::1]/path", + "http://[2001:db8::2]/path", + ); +} + #[test] fn test_insecure_cookies_cannot_evict_secure_cookie() { let mut storage = CookieStorage::new(5);