diff --git a/crates/xfdf/src/lib.rs b/crates/xfdf/src/lib.rs index 5c0be5232..a6da88f4d 100644 --- a/crates/xfdf/src/lib.rs +++ b/crates/xfdf/src/lib.rs @@ -235,7 +235,7 @@ fn hex(c: &[f64]) -> Option { fn parse_hex(s: &str) -> Option<[f64; 3]> { let h = s.trim().trim_start_matches('#'); - if h.len() != 6 { + if h.len() != 6 || !h.bytes().all(|b| b.is_ascii_hexdigit()) { return None; } let p = |i: usize| h.get(i..i + 2).and_then(|s| u8::from_str_radix(s, 16).ok()).map(|v| f64::from(v) / 255.0); diff --git a/crates/xfdf/src/tests.rs b/crates/xfdf/src/tests.rs index fb88da37b..80e7d8049 100644 --- a/crates/xfdf/src/tests.rs +++ b/crates/xfdf/src/tests.rs @@ -1759,6 +1759,15 @@ fn an_imported_redaction_rect_with_a_non_number_is_not_used() { assert!(mark.get(b"QuadPoints").is_none(), "quads were drawn from a malformed /Rect: {mark:?}"); } +#[test] +fn a_colour_with_non_hex_digits_is_rejected() { + assert!(parse_hex("#+f+f+f").is_none()); + assert!(parse_hex("#+1+2+3").is_none()); + assert!(parse_hex("#-1-2-3").is_none()); + assert!(parse_hex("#ff00zz").is_none()); + assert_eq!(parse_hex("#FF8000").map(|c| c[0]), Some(1.0)); +} + /// An FDF body with `body` as its `/FDF` dictionary contents and `objects` (numbered from 2). fn fdf_with(body: &str, objects: &[String]) -> Vec { let mut out = format!("%FDF-1.2\n1 0 obj\n<< /FDF << {body} >> >>\nendobj\n");