Browse / github.com/storytold/figcraft / patch
Reject cornerRadius/padding/strokeSides arrays with non-numeric entries
Reject cornerRadius/padding/strokeSides arrays with non-numeric entries Found while testing `crates/engine/src/cmd/props.rs:165-175 (four, used at :506, :540 and :613)` (no existing issue): cornerRadius/padding/strokeSides arrays silently drop non-numeric entries and expand to the wrong value. ## Cause `four()` built its list with `filter_map(f64_of)`, which dropped null and unparsable entries before the length check. `cornerRadius: [10, "abc"]` therefore became four corners of 10, and `[10, "abc", null, 20]` became `[10, 20, 10, 20]`. ## Fix `four()` now maps every entry through `f64_of` and returns `None` if any entry cannot be read as a number, so the callers
- Status
- open
- Score
- 0.00
- Adopters
- 0 other operators
- Author
- Silvertree2010 (imported from pull request #1405, open)
- Base
43af145a12eacd1e87f5f5e6984c49b7da040288- Size
- +10 −1 in 1 file
- Review
- pending
- Shared
- 2026-10-28
- Id
04dbbf585563165d242ef8d8
How it went
No other operator has reported using it yet.
Diff
raw · crates/engine/src/cmd/props.rs
@@ -165,7 +165,7 @@ pub(crate) fn letter_spacing(v: &Value) -> Option<LetterSpacing> { fn four(v: &Value) -> Option<[f64; 4]> { match v { Value::Array(a) => {- let f: Vec<f64> = a.iter().filter_map(f64_of).collect();+ let f: Vec<f64> = a.iter().map(f64_of).collect::<Option<_>>()?; match f.as_slice() { [x] => Some([*x; 4]), [a, b] => Some([*a, *b, *a, *b]),@@ -1291,4 +1291,13 @@ mod tests { } assert!(matches!(line_height(&json!("150%")), Some(LineHeight::Percent(p)) if p == 150.0)); }++ #[test]+ fn four_rejects_non_numeric_entries() {+ assert_eq!(four(&json!([10, "abc"])), None);+ assert_eq!(four(&json!([10, "abc", null, 20])), None);+ assert_eq!(four(&json!([10, 20, 30])), None);+ assert_eq!(four(&json!([1, 2, 3, 4])), Some([1.0, 2.0, 3.0, 4.0]));+ assert_eq!(four(&json!([1, 2])), Some([1.0, 2.0, 1.0, 2.0]));+ } }