diff --git a/crates/agent_ui/src/mention_set.rs b/crates/agent_ui/src/mention_set.rs index f62181c9f3d..8c98b9458bb 100644 --- a/crates/agent_ui/src/mention_set.rs +++ b/crates/agent_ui/src/mention_set.rs @@ -211,10 +211,7 @@ impl MentionSet { ); let crease = if let MentionUri::File { abs_path } = &mention_uri - && let Some(extension) = abs_path.extension() - && let Some(extension) = extension.to_str() - && Img::extensions().contains(&extension) - && !extension.contains("svg") + && is_raster_image_path(abs_path) { let Some(project_path) = project .read(cx) @@ -343,12 +340,8 @@ impl MentionSet { else { return Task::ready(Err(anyhow!("project path not found"))); }; - let extension = abs_path - .extension() - .and_then(OsStr::to_str) - .unwrap_or_default(); - if Img::extensions().contains(&extension) && !extension.contains("svg") { + if is_raster_image_path(&abs_path) { if !supports_images { return Task::ready(Err(anyhow!("This model does not support images yet"))); } @@ -723,6 +716,25 @@ mod tests { other => panic!("Expected selection mention to resolve as text, got {other:?}"), } } + + #[test] + fn test_is_raster_image_path_is_case_insensitive() { + // Regression test for #54308: drag-and-dropping a file whose extension + // is uppercase (e.g. `.PNG`) used to be treated as a non-image file. + assert!(is_raster_image_path(Path::new("/tmp/image.png"))); + assert!(is_raster_image_path(Path::new("/tmp/image.PNG"))); + assert!(is_raster_image_path(Path::new("/tmp/image.Png"))); + assert!(is_raster_image_path(Path::new("/tmp/photo.JPEG"))); + assert!(is_raster_image_path(Path::new("/tmp/animation.GIF"))); + + // SVG is handled via a different code path and must not be reported here. + assert!(!is_raster_image_path(Path::new("/tmp/icon.svg"))); + assert!(!is_raster_image_path(Path::new("/tmp/icon.SVG"))); + + // Non-image extensions and paths with no extension. + assert!(!is_raster_image_path(Path::new("/tmp/notes.txt"))); + assert!(!is_raster_image_path(Path::new("/tmp/README"))); + } } /// Inserts a list of images into the editor as context mentions. @@ -846,6 +858,20 @@ fn image_format_from_external_content(format: image::ImageFormat) -> Option bool { + let Some(extension) = path.extension().and_then(OsStr::to_str) else { + return false; + }; + if extension.eq_ignore_ascii_case("svg") { + return false; + } + Img::extensions() + .iter() + .any(|known| known.eq_ignore_ascii_case(extension)) +} + pub(crate) fn load_external_image_from_path( path: &Path, default_name: &SharedString,