Reject bare or signed second token in mixed distances (#2011)

Found while testing crates/engine/src/units.rs:176-179 (parse_mixed)

Co-authored-by: Claude Haiku 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
This commit is contained in:
NetterSilver
2026-10-24 01:59:50 -04:00
committed by GitHub
co-authored by Claude Haiku 5.5 Brandon Thomas
parent b062030a03
commit c66f6f45b8
+14 -1
View File
@@ -193,7 +193,13 @@ fn parse_mixed(s: &str) -> Option<f64> {
}; };
match parts.as_slice() { match parts.as_slice() {
[a] => frac(a), [a] => frac(a),
[a, b] => Some(a.parse::<f64>().ok()? + frac(b)?), [a, b] => {
let (n, d) = b.split_once('/')?;
if n.trim().starts_with(['-', '+']) || d.trim().starts_with(['-', '+']) {
return None;
}
Some(a.parse::<f64>().ok()? + frac(b)?)
}
_ => None, _ => None,
} }
} }
@@ -350,6 +356,13 @@ pub const DEG: f64 = PI / 180.0;
mod tests { mod tests {
use super::*; use super::*;
#[test]
fn mixed_distance_needs_a_positive_fraction_after_the_whole_number() {
assert_eq!(parse_distance("6 1/2"), Some(6.5));
assert_eq!(parse_distance("5 5"), None);
assert_eq!(parse_distance("1 -1/2"), None);
}
#[test] #[test]
fn huge_architectural_and_fractional_distances_do_not_saturate() { fn huge_architectural_and_fractional_distances_do_not_saturate() {
for lunits in [4, 5] { for lunits in [4, 5] {