From 8c3c969938d55eeec62c33a639da5d801aef5e7a Mon Sep 17 00:00:00 2001 From: Shocker Date: Wed, 29 Apr 2026 23:32:48 +0300 Subject: [PATCH] Fix favicon fetching to check all icon links instead of just the first one (#6880) * Fix favicon fetching to check all icon links instead of just the first one * revert max icons limit removal * optimize code * code formatting --- src/api/icons.rs | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/api/icons.rs b/src/api/icons.rs index b3a66f4d..5c9ed113 100644 --- a/src/api/icons.rs +++ b/src/api/icons.rs @@ -496,7 +496,8 @@ async fn download_icon(domain: &str) -> Result<(Bytes, Option<&str>), Error> { use data_url::DataUrl; - for icon in icon_result.iconlist.iter().take(5) { + let mut icons = icon_result.iconlist.iter().take(5).peekable(); + while let Some(icon) = icons.next() { if icon.href.starts_with("data:image") { let Ok(datauri) = DataUrl::process(&icon.href) else { continue; @@ -524,11 +525,23 @@ async fn download_icon(domain: &str) -> Result<(Bytes, Option<&str>), Error> { _ => debug!("Extracted icon from data:image uri is invalid"), }; } else { - let res = get_page_with_referer(&icon.href, &icon_result.referer).await?; + debug!("Trying {}", icon.href); + // Make sure all icons are checked before returning error + let res = match get_page_with_referer(&icon.href, &icon_result.referer).await { + Ok(r) => r, + Err(e) if icons.peek().is_none() => return Err(e), + Err(e) if CustomHttpClientError::downcast_ref(&e).is_some() => return Err(e), // If blacklisted stop immediately instead of checking the rest of the icons. see explanation and actual handling inside get_icon() + Err(e) => { + warn!("Unable to download icon: {e:?}"); + + // Continue to next icon + continue; + } + }; buffer = stream_to_bytes_limit(res, 5120 * 1024).await?; // 5120KB/5MB for each icon max (Same as icons.bitwarden.net) - // Check if the icon type is allowed, else try an icon from the list. + // Check if the icon type is allowed, else try another icon from the list. icon_type = get_icon_type(&buffer); if icon_type.is_none() { buffer.clear();