Reject multiple leading '#' in Color::from_hex

Found while testing crates/color/src/lib.rs:125

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
NetterSilver
2026-10-20 17:49:45 +00:00
co-authored by Claude Haiku 5.5
parent d9c924c3ba
commit 570144ee90
2 changed files with 11 additions and 1 deletions
+2 -1
View File
@@ -122,7 +122,8 @@ impl Color {
/// Parse hex the way the colour field does: `#` optional, 1, 2, 3, 4, 6 or 8 digits
/// (`F` → `FFFFFF`, `AB` → `ABABAB`, `ABC` → `AABBCC`).
pub fn from_hex(s: &str) -> Option<Self> {
let s = s.trim().trim_start_matches('#');
let s = s.trim();
let s = s.strip_prefix('#').unwrap_or(s);
if !s.chars().all(|c| c.is_ascii_hexdigit()) {
return None;
}
+9
View File
@@ -114,3 +114,12 @@ fn infinite_channels_clamp() {
let c = Color::new(f32::INFINITY, f32::NEG_INFINITY, f32::NAN, f32::INFINITY);
assert_eq!((c.r, c.g, c.b, c.a), (1.0, 0.0, 0.0, 1.0));
}
#[test]
fn hex_allows_at_most_one_leading_hash() {
assert!(Color::from_hex("##ff0000").is_none());
assert!(Color::from_hex("###fff").is_none());
assert!(Color::from_hex_or_name("##ff0000").is_none());
assert_eq!(Color::from_hex("#ff0000").unwrap().to_hex(), "FF0000");
assert_eq!(Color::from_hex("ff0000").unwrap().to_hex(), "FF0000");
}