mirror of
https://github.com/storytold/filmcraft.git
synced 2026-10-24 10:10:05 -06:00
Reject non-hex characters in colour hex parsing (#2600)
Accept only ASCII hexadecimal digits after a single optional hash in color strings.
This commit is contained in:
+15
-1
@@ -296,7 +296,11 @@ pub fn hsl_to_rgb(h: f32, s: f32, l: f32) -> [f32; 3] {
|
||||
|
||||
/// Parse `#rrggbb` / `#rrggbbaa` into 0..1 floats.
|
||||
pub fn parse_hex(s: &str) -> Option<[f32; 4]> {
|
||||
let s = s.trim().trim_start_matches('#');
|
||||
let s = s.trim();
|
||||
let s = s.strip_prefix('#').unwrap_or(s);
|
||||
if !s.bytes().all(|b| b.is_ascii_hexdigit()) {
|
||||
return None;
|
||||
}
|
||||
let b = |i: usize| u8::from_str_radix(s.get(i..i + 2)?, 16).ok().map(|v| v as f32 / 255.0);
|
||||
match s.len() {
|
||||
6 => Some([b(0)?, b(2)?, b(4)?, 1.0]),
|
||||
@@ -318,6 +322,16 @@ pub fn to_hex(c: [f32; 4]) -> String {
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn parse_hex_rejects_signs() {
|
||||
assert_eq!(parse_hex("#+f+f+f"), None);
|
||||
assert_eq!(parse_hex("#-f-f-f"), None);
|
||||
assert_eq!(parse_hex("##0f0f0f"), None);
|
||||
assert_eq!(parse_hex("#0f0f0"), None);
|
||||
assert!(parse_hex("#0f0f0f").is_some());
|
||||
assert!(parse_hex("0f0f0f80").is_some());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ycbcr_roundtrip() {
|
||||
for m in [Matrix::Bt601, Matrix::Bt709, Matrix::Bt2020Ncl] {
|
||||
|
||||
@@ -82,7 +82,11 @@ fn parse_color(v: &Value) -> Option<[u8; 4]> {
|
||||
_ => None,
|
||||
};
|
||||
}
|
||||
let h = v.as_str()?.trim_start_matches('#');
|
||||
let h = v.as_str()?;
|
||||
let h = h.strip_prefix('#').unwrap_or(h);
|
||||
if !h.bytes().all(|b| b.is_ascii_hexdigit()) {
|
||||
return None;
|
||||
}
|
||||
let b = |i: usize| u8::from_str_radix(h.get(i..i + 2)?, 16).ok();
|
||||
match h.len() {
|
||||
6 => Some([b(0)?, b(2)?, b(4)?, 255]),
|
||||
|
||||
Reference in New Issue
Block a user